2 * Copyright (c) 1999-2005 Sendmail, Inc. and its suppliers.
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
13 SM_RCSID("@(#)$Id: milter.c,v 8.229 2005/03/02 02:32:34 ca Exp $")
16 # include <libmilter/mfapi.h>
17 # include <libmilter/mfdef.h>
20 # include <sys/time.h>
23 # if NETINET || NETINET6
24 # include <arpa/inet.h>
25 # if _FFR_MILTER_NAGLE
26 # include <netinet/tcp.h>
27 # endif /* _FFR_MILTER_NAGLE */
28 # endif /* NETINET || NETINET6 */
30 # include <sm/fdset.h>
32 static void milter_connect_timeout __P((int));
33 static void milter_error __P((struct milter *, ENVELOPE *));
34 static int milter_open __P((struct milter *, bool, ENVELOPE *));
35 static void milter_parse_timeouts __P((char *, struct milter *));
37 static char *MilterConnectMacros[MAXFILTERMACROS + 1];
38 static char *MilterHeloMacros[MAXFILTERMACROS + 1];
39 static char *MilterEnvFromMacros[MAXFILTERMACROS + 1];
40 static char *MilterEnvRcptMacros[MAXFILTERMACROS + 1];
41 static char *MilterDataMacros[MAXFILTERMACROS + 1];
42 static char *MilterEOMMacros[MAXFILTERMACROS + 1];
43 static size_t MilterMaxDataSize = MILTER_MAX_DATA_SIZE;
45 # define MILTER_CHECK_DONE_MSG() \
46 if (*state == SMFIR_REPLYCODE || \
47 *state == SMFIR_REJECT || \
48 *state == SMFIR_DISCARD || \
49 *state == SMFIR_TEMPFAIL) \
51 /* Abort the filters to let them know we are done with msg */ \
55 # define MILTER_CHECK_ERROR(initial, action) \
56 if (!initial && tTd(71, 100)) \
58 if (e->e_quarmsg == NULL) \
60 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, \
62 macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), \
66 else if (tTd(71, 101)) \
68 if (e->e_quarmsg == NULL) \
70 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, \
72 macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), \
76 else if (bitnset(SMF_TEMPFAIL, m->mf_flags)) \
77 *state = SMFIR_TEMPFAIL; \
78 else if (bitnset(SMF_TEMPDROP, m->mf_flags)) \
79 *state = SMFIR_SHUTDOWN; \
80 else if (bitnset(SMF_REJECT, m->mf_flags)) \
81 *state = SMFIR_REJECT; \
85 # define MILTER_CHECK_REPLYCODE(default) \
86 if (response == NULL || \
87 strlen(response) + 1 != (size_t) rlen || \
89 (response[0] != '4' && response[0] != '5') || \
90 !isascii(response[1]) || !isdigit(response[1]) || \
91 !isascii(response[2]) || !isdigit(response[2])) \
93 if (response != NULL) \
94 sm_free(response); /* XXX */ \
95 response = newstr(default); \
99 char *ptr = response; \
101 /* Check for unprotected %'s in the string */ \
102 while (*ptr != '\0') \
104 if (*ptr == '%' && *++ptr != '%') \
106 sm_free(response); /* XXX */ \
107 response = newstr(default); \
114 # define MILTER_DF_ERROR(msg) \
116 int save_errno = errno; \
120 sm_dprintf(msg, dfname, sm_errstring(save_errno)); \
123 if (MilterLogLevel > 0) \
124 sm_syslog(LOG_ERR, e->e_id, msg, dfname, sm_errstring(save_errno)); \
125 if (SuperSafe == SAFE_REALLY) \
127 if (e->e_dfp != NULL) \
129 (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT); \
132 e->e_flags &= ~EF_HAS_DF; \
134 errno = save_errno; \
138 ** MILTER_TIMEOUT -- make sure socket is ready in time
141 ** routine -- routine name for debug/logging
142 ** secs -- number of seconds in timeout
143 ** write -- waiting to read or write?
144 ** started -- whether this is part of a previous sequence
146 ** Assumes 'm' is a milter structure for the current socket.
149 # define MILTER_TIMEOUT(routine, secs, write, started) \
156 if (SM_FD_SETSIZE > 0 && m->mf_sock >= SM_FD_SETSIZE) \
159 sm_dprintf("milter_%s(%s): socket %d is larger than FD_SETSIZE %d\n", \
160 (routine), m->mf_name, m->mf_sock, \
162 if (MilterLogLevel > 0) \
163 sm_syslog(LOG_ERR, e->e_id, \
164 "Milter (%s): socket(%s) %d is larger than FD_SETSIZE %d", \
165 m->mf_name, (routine), m->mf_sock, \
167 milter_error(m, e); \
174 SM_FD_SET(m->mf_sock, &fds); \
175 tv.tv_sec = (secs); \
177 ret = select(m->mf_sock + 1, \
178 (write) ? NULL : &fds, \
179 (write) ? &fds : NULL, \
181 } while (ret < 0 && errno == EINTR); \
187 sm_dprintf("milter_%s(%s): timeout\n", (routine), \
189 if (MilterLogLevel > 0) \
190 sm_syslog(LOG_ERR, e->e_id, \
191 "Milter (%s): %s %s %s %s", \
192 m->mf_name, "timeout", \
193 started ? "during" : "before", \
194 "data", (routine)); \
195 milter_error(m, e); \
199 save_errno = errno; \
201 sm_dprintf("milter_%s(%s): select: %s\n", (routine), \
202 m->mf_name, sm_errstring(save_errno)); \
203 if (MilterLogLevel > 0) \
205 sm_syslog(LOG_ERR, e->e_id, \
206 "Milter (%s): select(%s): %s", \
207 m->mf_name, (routine), \
208 sm_errstring(save_errno)); \
210 milter_error(m, e); \
214 if (SM_FD_ISSET(m->mf_sock, &fds)) \
217 sm_dprintf("milter_%s(%s): socket not ready\n", \
218 (routine), m->mf_name); \
219 if (MilterLogLevel > 0) \
221 sm_syslog(LOG_ERR, e->e_id, \
222 "Milter (%s): socket(%s) not ready", \
223 m->mf_name, (routine)); \
225 milter_error(m, e); \
231 ** Low level functions
235 ** MILTER_READ -- read from a remote milter filter
238 ** m -- milter to read from.
239 ** cmd -- return param for command read.
240 ** rlen -- return length of response string.
241 ** to -- timeout in seconds.
242 ** e -- current envelope.
245 ** response string (may be NULL)
249 milter_sysread(m, buf, sz, to, e)
256 time_t readstart = 0;
258 bool started = false;
263 readstart = curtime();
272 if (now - readstart >= to)
275 sm_dprintf("milter_read (%s): %s %s %s",
276 m->mf_name, "timeout",
277 started ? "during" : "before",
279 if (MilterLogLevel > 0)
280 sm_syslog(LOG_ERR, e->e_id,
281 "Milter (%s): %s %s %s",
282 m->mf_name, "timeout",
283 started ? "during" : "before",
288 to -= now - readstart;
290 MILTER_TIMEOUT("read", to, false, started);
293 len = read(m->mf_sock, buf + curl, sz - curl);
297 int save_errno = errno;
300 sm_dprintf("milter_read(%s): read returned %ld: %s\n",
301 m->mf_name, (long) len,
302 sm_errstring(save_errno));
303 if (MilterLogLevel > 0)
304 sm_syslog(LOG_ERR, e->e_id,
305 "Milter (%s): read returned %ld: %s",
306 m->mf_name, (long) len,
307 sm_errstring(save_errno));
314 if (len == 0 || curl >= sz)
322 sm_dprintf("milter_read(%s): cmd read returned %ld, expecting %ld\n",
323 m->mf_name, (long) curl, (long) sz);
324 if (MilterLogLevel > 0)
325 sm_syslog(LOG_ERR, e->e_id,
326 "milter_read(%s): cmd read returned %ld, expecting %ld",
327 m->mf_name, (long) curl, (long) sz);
335 milter_read(m, cmd, rlen, to, e)
342 time_t readstart = 0;
345 # if _FFR_MILTER_NAGLE
349 # endif /* _FFR_MILTER_NAGLE */
351 char data[MILTER_LEN_BYTES + 1];
355 if (MilterLogLevel > 0)
356 sm_syslog(LOG_ERR, e->e_id,
357 "milter_read(%s): socket closed",
367 readstart = curtime();
369 # if _FFR_MILTER_NAGLE
371 setsockopt(m->mf_sock, IPPROTO_TCP, TCP_CORK, (char *)&cork,
374 # endif /* _FFR_MILTER_NAGLE */
376 if (milter_sysread(m, data, sizeof data, to, e) == NULL)
379 # if _FFR_MILTER_NAGLE
382 setsockopt(m->mf_sock, IPPROTO_TCP, TCP_CORK, (char *)&cork,
385 # endif /* _FFR_MILTER_NAGLE */
393 if (now - readstart >= to)
396 sm_dprintf("milter_read(%s): timeout before data read\n",
398 if (MilterLogLevel > 0)
399 sm_syslog(LOG_ERR, e->e_id,
400 "Milter read(%s): timeout before data read",
405 to -= now - readstart;
408 *cmd = data[MILTER_LEN_BYTES];
409 data[MILTER_LEN_BYTES] = '\0';
410 (void) memcpy(&i, data, MILTER_LEN_BYTES);
414 sm_dprintf("milter_read(%s): expecting %ld bytes\n",
415 m->mf_name, (long) expl);
420 sm_dprintf("milter_read(%s): read size %ld out of range\n",
421 m->mf_name, (long) expl);
422 if (MilterLogLevel > 0)
423 sm_syslog(LOG_ERR, e->e_id,
424 "milter_read(%s): read size %ld out of range",
425 m->mf_name, (long) expl);
433 buf = (char *) xalloc(expl);
435 if (milter_sysread(m, buf, expl, to, e) == NULL)
437 sm_free(buf); /* XXX */
442 sm_dprintf("milter_read(%s): Returning %*s\n",
443 m->mf_name, (int) expl, buf);
449 ** MILTER_WRITE -- write to a remote milter filter
452 ** m -- milter to read from.
453 ** cmd -- command to send.
454 ** buf -- optional command data.
455 ** len -- length of buf.
456 ** to -- timeout in seconds.
457 ** e -- current envelope.
460 ** buf if successful, NULL otherwise
461 ** Not actually used anywhere but function prototype
462 ** must match milter_read()
466 milter_write(m, cmd, buf, len, to, e)
474 time_t writestart = (time_t) 0;
478 char data[MILTER_LEN_BYTES + 1];
479 bool started = false;
480 struct iovec vector[2];
483 ** At most two buffers will be written, though
484 ** only one may actually be used (see num_vectors).
485 ** The first is the size/command and the second is the command data.
488 if (len < 0 || len > MilterMaxDataSize)
491 sm_dprintf("milter_write(%s): length %ld out of range\n",
492 m->mf_name, (long) len);
493 if (MilterLogLevel > 0)
494 sm_syslog(LOG_ERR, e->e_id,
495 "milter_write(%s): length %ld out of range",
496 m->mf_name, (long) len);
502 if (MilterLogLevel > 0)
503 sm_syslog(LOG_ERR, e->e_id,
504 "milter_write(%s): socket closed",
511 sm_dprintf("milter_write(%s): cmd %c, len %ld\n",
512 m->mf_name, cmd, (long) len);
514 nl = htonl(len + 1); /* add 1 for the cmd char */
515 (void) memcpy(data, (char *) &nl, MILTER_LEN_BYTES);
516 data[MILTER_LEN_BYTES] = cmd;
517 sl = MILTER_LEN_BYTES + 1;
519 /* set up the vector for the size / command */
520 vector[0].iov_base = (void *) data;
521 vector[0].iov_len = sl;
524 ** Determine if there is command data. If so, there will be two
525 ** vectors. If not, there will be only one. The vectors are set
526 ** up here and 'num_vectors' and 'sl' are set appropriately.
529 /* NOTE: len<0 has already been checked for. Pedantic */
530 if (len <= 0 || buf == NULL)
532 /* There is no command data -- only a size / command data */
538 ** There is both size / command and command data.
539 ** Set up the vector for the command data.
544 vector[1].iov_base = (void *) buf;
545 vector[1].iov_len = len;
548 sm_dprintf("milter_write(%s): Sending %*s\n",
549 m->mf_name, (int) len, buf);
554 writestart = curtime();
555 MILTER_TIMEOUT("write", to, true, started);
558 /* write the vector(s) */
559 i = writev(m->mf_sock, vector, num_vectors);
562 int save_errno = errno;
565 sm_dprintf("milter_write(%s): write(%c) returned %ld, expected %ld: %s\n",
566 m->mf_name, cmd, (long) i, (long) sl,
567 sm_errstring(save_errno));
568 if (MilterLogLevel > 0)
569 sm_syslog(LOG_ERR, e->e_id,
570 "Milter (%s): write(%c) returned %ld, expected %ld: %s",
571 m->mf_name, cmd, (long) i, (long) sl,
572 sm_errstring(save_errno));
584 ** MILTER_OPEN -- connect to remote milter filter
587 ** m -- milter to connect to.
588 ** parseonly -- parse but don't connect.
589 ** e -- current envelope.
592 ** connected socket if successful && !parseonly,
593 ** 0 upon parse success if parseonly,
597 static jmp_buf MilterConnectTimeout;
600 milter_open(m, parseonly, e)
606 SOCKADDR_LEN_T addrlen = 0;
612 struct hostent *hp = NULL;
615 if (m->mf_conn == NULL || m->mf_conn[0] == '\0')
618 sm_dprintf("X%s: empty or missing socket information\n",
621 syserr("X%s: empty or missing socket information",
623 else if (MilterLogLevel > 0)
624 sm_syslog(LOG_ERR, e->e_id,
625 "Milter (%s): empty or missing socket information",
631 /* protocol:filename or protocol:port@host */
632 memset(&addr, '\0', sizeof addr);
634 colon = strchr(p, ':');
642 /* default to AF_UNIX */
643 addr.sa.sa_family = AF_UNIX;
646 /* default to AF_INET */
647 addr.sa.sa_family = AF_INET;
650 /* default to AF_INET6 */
651 addr.sa.sa_family = AF_INET6;
652 # else /* NETINET6 */
653 /* no protocols available */
654 if (MilterLogLevel > 0)
655 sm_syslog(LOG_ERR, e->e_id,
656 "Milter (%s): no valid socket protocols available",
660 # endif /* NETINET6 */
661 # endif /* NETINET */
662 # endif /* NETUNIX */
665 else if (sm_strcasecmp(p, "unix") == 0 ||
666 sm_strcasecmp(p, "local") == 0)
667 addr.sa.sa_family = AF_UNIX;
668 # endif /* NETUNIX */
670 else if (sm_strcasecmp(p, "inet") == 0)
671 addr.sa.sa_family = AF_INET;
672 # endif /* NETINET */
674 else if (sm_strcasecmp(p, "inet6") == 0)
675 addr.sa.sa_family = AF_INET6;
676 # endif /* NETINET6 */
679 # ifdef EPROTONOSUPPORT
680 errno = EPROTONOSUPPORT;
681 # else /* EPROTONOSUPPORT */
683 # endif /* EPROTONOSUPPORT */
685 sm_dprintf("X%s: unknown socket type %s\n",
688 syserr("X%s: unknown socket type %s",
690 else if (MilterLogLevel > 0)
691 sm_syslog(LOG_ERR, e->e_id,
692 "Milter (%s): unknown socket type %s",
701 /* default to AF_UNIX */
702 addr.sa.sa_family = AF_UNIX;
707 if (addr.sa.sa_family == AF_UNIX)
709 long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_EXECOK;
712 if (strlen(colon) >= sizeof addr.sunix.sun_path)
715 sm_dprintf("X%s: local socket name %s too long\n",
719 syserr("X%s: local socket name %s too long",
721 else if (MilterLogLevel > 0)
722 sm_syslog(LOG_ERR, e->e_id,
723 "Milter (%s): local socket name %s too long",
728 errno = safefile(colon, RunAsUid, RunAsGid, RunAsUserName, sff,
729 S_IRUSR|S_IWUSR, NULL);
731 /* if just parsing .cf file, socket doesn't need to exist */
732 if (parseonly && errno == ENOENT)
734 if (OpMode == MD_DAEMON ||
735 OpMode == MD_FGDAEMON)
736 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
737 "WARNING: X%s: local socket name %s missing\n",
742 /* if not safe, don't create */
745 sm_dprintf("X%s: local socket name %s unsafe\n",
750 if (OpMode == MD_DAEMON ||
751 OpMode == MD_FGDAEMON ||
753 syserr("X%s: local socket name %s unsafe",
756 else if (MilterLogLevel > 0)
757 sm_syslog(LOG_ERR, e->e_id,
758 "Milter (%s): local socket name %s unsafe",
764 (void) sm_strlcpy(addr.sunix.sun_path, colon,
765 sizeof addr.sunix.sun_path);
766 addrlen = sizeof (struct sockaddr_un);
769 # endif /* NETUNIX */
770 # if NETINET || NETINET6
773 || addr.sa.sa_family == AF_INET
774 # endif /* NETINET */
776 || addr.sa.sa_family == AF_INET6
777 # endif /* NETINET6 */
782 /* Parse port@host */
783 at = strchr(colon, '@');
787 sm_dprintf("X%s: bad address %s (expected port@host)\n",
790 syserr("X%s: bad address %s (expected port@host)",
792 else if (MilterLogLevel > 0)
793 sm_syslog(LOG_ERR, e->e_id,
794 "Milter (%s): bad address %s (expected port@host)",
800 if (isascii(*colon) && isdigit(*colon))
801 port = htons((unsigned short) atoi(colon));
804 # ifdef NO_GETSERVBYNAME
806 sm_dprintf("X%s: invalid port number %s\n",
809 syserr("X%s: invalid port number %s",
811 else if (MilterLogLevel > 0)
812 sm_syslog(LOG_ERR, e->e_id,
813 "Milter (%s): invalid port number %s",
817 # else /* NO_GETSERVBYNAME */
818 register struct servent *sp;
820 sp = getservbyname(colon, "tcp");
825 sm_dprintf("X%s: unknown port name %s\n",
829 syserr("X%s: unknown port name %s",
831 else if (MilterLogLevel > 0)
832 sm_syslog(LOG_ERR, e->e_id,
833 "Milter (%s): unknown port name %s",
839 # endif /* NO_GETSERVBYNAME */
846 end = strchr(at, ']');
851 unsigned long hid = INADDR_NONE;
852 # endif /* NETINET */
854 struct sockaddr_in6 hid6;
855 # endif /* NETINET6 */
859 if (addr.sa.sa_family == AF_INET &&
860 (hid = inet_addr(&at[1])) != INADDR_NONE)
862 addr.sin.sin_addr.s_addr = hid;
863 addr.sin.sin_port = port;
866 # endif /* NETINET */
868 (void) memset(&hid6, '\0', sizeof hid6);
869 if (addr.sa.sa_family == AF_INET6 &&
870 anynet_pton(AF_INET6, &at[1],
871 &hid6.sin6_addr) == 1)
873 addr.sin6.sin6_addr = hid6.sin6_addr;
874 addr.sin6.sin6_port = port;
877 # endif /* NETINET6 */
882 sm_dprintf("X%s: Invalid numeric domain spec \"%s\"\n",
885 syserr("X%s: Invalid numeric domain spec \"%s\"",
887 else if (MilterLogLevel > 0)
888 sm_syslog(LOG_ERR, e->e_id,
889 "Milter (%s): Invalid numeric domain spec \"%s\"",
898 sm_dprintf("X%s: Invalid numeric domain spec \"%s\"\n",
901 syserr("X%s: Invalid numeric domain spec \"%s\"",
903 else if (MilterLogLevel > 0)
904 sm_syslog(LOG_ERR, e->e_id,
905 "Milter (%s): Invalid numeric domain spec \"%s\"",
913 hp = sm_gethostbyname(at, addr.sa.sa_family);
918 sm_dprintf("X%s: Unknown host name %s\n",
922 syserr("X%s: Unknown host name %s",
924 else if (MilterLogLevel > 0)
925 sm_syslog(LOG_ERR, e->e_id,
926 "Milter (%s): Unknown host name %s",
931 addr.sa.sa_family = hp->h_addrtype;
932 switch (hp->h_addrtype)
936 memmove(&addr.sin.sin_addr,
937 hp->h_addr, INADDRSZ);
938 addr.sin.sin_port = port;
939 addrlen = sizeof (struct sockaddr_in);
942 # endif /* NETINET */
946 memmove(&addr.sin6.sin6_addr,
947 hp->h_addr, IN6ADDRSZ);
948 addr.sin6.sin6_port = port;
949 addrlen = sizeof (struct sockaddr_in6);
952 # endif /* NETINET6 */
956 sm_dprintf("X%s: Unknown protocol for %s (%d)\n",
960 syserr("X%s: Unknown protocol for %s (%d)",
961 m->mf_name, at, hp->h_addrtype);
962 else if (MilterLogLevel > 0)
963 sm_syslog(LOG_ERR, e->e_id,
964 "Milter (%s): Unknown protocol for %s (%d)",
970 # endif /* NETINET6 */
976 # endif /* NETINET || NETINET6 */
979 sm_dprintf("X%s: unknown socket protocol\n",
982 syserr("X%s: unknown socket protocol", m->mf_name);
983 else if (MilterLogLevel > 0)
984 sm_syslog(LOG_ERR, e->e_id,
985 "Milter (%s): unknown socket protocol",
991 /* just parsing through? */
994 m->mf_state = SMFS_READY;
998 # endif /* NETINET6 */
1003 if (m->mf_state != SMFS_READY &&
1004 m->mf_state != SMFS_CLOSED)
1006 /* shouldn't happen */
1008 sm_dprintf("Milter (%s): Trying to open filter in state %c\n",
1009 m->mf_name, (char) m->mf_state);
1014 # endif /* NETINET6 */
1018 /* nope, actually connecting */
1021 sock = socket(addr.sa.sa_family, SOCK_STREAM, 0);
1026 sm_dprintf("Milter (%s): error creating socket: %s\n",
1028 sm_errstring(save_errno));
1029 if (MilterLogLevel > 0)
1030 sm_syslog(LOG_ERR, e->e_id,
1031 "Milter (%s): error creating socket: %s",
1032 m->mf_name, sm_errstring(save_errno));
1037 # endif /* NETINET6 */
1041 if (setjmp(MilterConnectTimeout) == 0)
1043 SM_EVENT *ev = NULL;
1046 if (m->mf_timeout[SMFTO_CONNECT] > 0)
1047 ev = sm_setevent(m->mf_timeout[SMFTO_CONNECT],
1048 milter_connect_timeout, 0);
1050 i = connect(sock, (struct sockaddr *) &addr, addrlen);
1059 /* couldn't connect.... try next address */
1064 sm_dprintf("milter_open (%s): open %s failed: %s\n",
1065 m->mf_name, at, sm_errstring(save_errno));
1066 if (MilterLogLevel > 13)
1067 sm_syslog(LOG_INFO, e->e_id,
1068 "Milter (%s): open %s failed: %s",
1069 m->mf_name, at, sm_errstring(save_errno));
1073 /* try next address */
1074 if (hp != NULL && hp->h_addr_list[addrno] != NULL)
1076 switch (addr.sa.sa_family)
1080 memmove(&addr.sin.sin_addr,
1081 hp->h_addr_list[addrno++],
1084 # endif /* NETINET */
1088 memmove(&addr.sin6.sin6_addr,
1089 hp->h_addr_list[addrno++],
1092 # endif /* NETINET6 */
1096 sm_dprintf("X%s: Unknown protocol for %s (%d)\n",
1099 if (MilterLogLevel > 0)
1100 sm_syslog(LOG_ERR, e->e_id,
1101 "Milter (%s): Unknown protocol for %s (%d)",
1107 # endif /* NETINET6 */
1115 sm_dprintf("X%s: error connecting to filter: %s\n",
1116 m->mf_name, sm_errstring(save_errno));
1117 if (MilterLogLevel > 0)
1118 sm_syslog(LOG_ERR, e->e_id,
1119 "Milter (%s): error connecting to filter: %s",
1120 m->mf_name, sm_errstring(save_errno));
1126 # endif /* NETINET6 */
1129 m->mf_state = SMFS_OPEN;
1136 # endif /* NETINET6 */
1137 # if _FFR_MILTER_NAGLE
1142 setsockopt(m->mf_sock, IPPROTO_TCP, TCP_NODELAY,
1143 (char *)&nodelay, sizeof(nodelay));
1145 # endif /* TCP_CORK */
1146 # endif /* _FFR_MILTER_NAGLE */
1151 milter_connect_timeout(ignore)
1155 ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
1156 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
1161 longjmp(MilterConnectTimeout, 1);
1164 ** MILTER_SETUP -- setup structure for a mail filter
1167 ** line -- the options line.
1179 register struct milter *m;
1182 /* collect the filter name */
1184 *p != '\0' && *p != ',' && !(isascii(*p) && isspace(*p));
1189 if (line[0] == '\0')
1191 syserr("name required for mail filter");
1194 m = (struct milter *) xalloc(sizeof *m);
1195 memset((char *) m, '\0', sizeof *m);
1196 m->mf_name = newstr(line);
1197 m->mf_state = SMFS_READY;
1199 m->mf_timeout[SMFTO_CONNECT] = (time_t) 300;
1200 m->mf_timeout[SMFTO_WRITE] = (time_t) 10;
1201 m->mf_timeout[SMFTO_READ] = (time_t) 10;
1202 m->mf_timeout[SMFTO_EOM] = (time_t) 300;
1204 /* now scan through and assign info from the fields */
1209 while (*p != '\0' &&
1210 (*p == ',' || (isascii(*p) && isspace(*p))))
1213 /* p now points to field code */
1215 while (*p != '\0' && *p != '=' && *p != ',')
1219 syserr("X%s: `=' expected", m->mf_name);
1222 while (isascii(*p) && isspace(*p))
1225 /* p now points to the field body */
1226 p = munchstring(p, &delimptr, ',');
1228 /* install the field into the filter struct */
1231 case 'S': /* socket */
1235 m->mf_conn = newstr(p);
1238 case 'F': /* Milter flags configured on MTA */
1239 for (; *p != '\0'; p++)
1241 if (!(isascii(*p) && isspace(*p)))
1242 setbitn(bitidx(*p), m->mf_flags);
1246 case 'T': /* timeouts */
1247 milter_parse_timeouts(p, m);
1251 syserr("X%s: unknown filter equate %c=",
1258 /* early check for errors */
1259 (void) milter_open(m, true, CurEnv);
1261 /* enter the filter into the symbol table */
1262 s = stab(m->mf_name, ST_MILTER, ST_ENTER);
1263 if (s->s_milter != NULL)
1264 syserr("X%s: duplicate filter definition", m->mf_name);
1269 ** MILTER_CONFIG -- parse option list into an array and check config
1271 ** Called when reading configuration file.
1274 ** spec -- the filter list.
1275 ** list -- the array to fill in.
1276 ** max -- the maximum number of entries in list.
1283 milter_config(spec, list, max)
1285 struct milter **list;
1291 /* leave one for the NULL signifying the end of the list */
1294 for (p = spec; p != NULL; )
1298 while (isascii(*p) && isspace(*p))
1304 if (numitems >= max)
1306 syserr("Too many filters defined, %d max", max);
1311 p = strpbrk(p, ";,");
1315 s = stab(spec, ST_MILTER, ST_FIND);
1318 syserr("InputFilter %s not defined", spec);
1319 ExitStat = EX_CONFIG;
1322 list[numitems++] = s->s_milter;
1324 list[numitems] = NULL;
1326 /* if not set, set to LogLevel */
1327 if (MilterLogLevel == -1)
1328 MilterLogLevel = LogLevel;
1331 ** MILTER_PARSE_TIMEOUTS -- parse timeout list
1333 ** Called when reading configuration file.
1336 ** spec -- the timeout list.
1337 ** m -- milter to set.
1344 milter_parse_timeouts(spec, m)
1354 /* now scan through and assign info from the fields */
1359 while (*p != '\0' &&
1360 (*p == ';' || (isascii(*p) && isspace(*p))))
1363 /* p now points to field code */
1365 while (*p != '\0' && *p != ':')
1369 syserr("X%s, T=: `:' expected", m->mf_name);
1372 while (isascii(*p) && isspace(*p))
1375 /* p now points to the field body */
1376 p = munchstring(p, &delimptr, ';');
1379 /* install the field into the filter struct */
1383 tcode = SMFTO_CONNECT;
1387 tcode = SMFTO_WRITE;
1400 sm_dprintf("X%s: %c unknown\n",
1402 syserr("X%s: unknown filter timeout %c",
1408 m->mf_timeout[tcode] = convtime(p, 's');
1410 sm_dprintf("X%s: %c=%ld\n",
1412 (u_long) m->mf_timeout[tcode]);
1418 ** MILTER_SET_OPTION -- set an individual milter option
1421 ** name -- the name of the option.
1422 ** val -- the value of the option.
1423 ** sticky -- if set, don't let other setoptions override
1430 /* set if Milter sub-option is stuck */
1431 static BITMAP256 StickyMilterOpt;
1433 static struct milteropt
1435 char *mo_name; /* long name of milter option */
1436 unsigned char mo_code; /* code for option */
1439 # define MO_MACROS_CONNECT 0x01
1440 { "macros.connect", MO_MACROS_CONNECT },
1441 # define MO_MACROS_HELO 0x02
1442 { "macros.helo", MO_MACROS_HELO },
1443 # define MO_MACROS_ENVFROM 0x03
1444 { "macros.envfrom", MO_MACROS_ENVFROM },
1445 # define MO_MACROS_ENVRCPT 0x04
1446 { "macros.envrcpt", MO_MACROS_ENVRCPT },
1447 # define MO_MACROS_DATA 0x05
1448 { "macros.data", MO_MACROS_DATA },
1449 # define MO_MACROS_EOM 0x06
1450 { "macros.eom", MO_MACROS_EOM },
1451 # define MO_LOGLEVEL 0x07
1452 { "loglevel", MO_LOGLEVEL },
1453 # if _FFR_MAXDATASIZE
1454 # define MO_MAXDATASIZE 0x08
1455 { "maxdatasize", MO_MAXDATASIZE },
1456 # endif /* _FFR_MAXDATASIZE */
1461 milter_set_option(name, val, sticky)
1467 register struct milteropt *mo;
1469 char **macros = NULL;
1471 if (tTd(37, 2) || tTd(64, 5))
1472 sm_dprintf("milter_set_option(%s = %s)", name, val);
1476 syserr("milter_set_option: invalid Milter option, must specify suboption");
1480 for (mo = MilterOptTab; mo->mo_name != NULL; mo++)
1482 if (sm_strcasecmp(mo->mo_name, name) == 0)
1486 if (mo->mo_name == NULL)
1488 syserr("milter_set_option: invalid Milter option %s", name);
1493 ** See if this option is preset for us.
1496 if (!sticky && bitnset(mo->mo_code, StickyMilterOpt))
1498 if (tTd(37, 2) || tTd(64,5))
1499 sm_dprintf(" (ignored)\n");
1503 if (tTd(37, 2) || tTd(64,5))
1506 switch (mo->mo_code)
1509 MilterLogLevel = atoi(val);
1512 #if _FFR_MAXDATASIZE
1513 case MO_MAXDATASIZE:
1514 MilterMaxDataSize = (size_t)atol(val);
1516 #endif /* _FFR_MAXDATASIZE */
1518 case MO_MACROS_CONNECT:
1520 macros = MilterConnectMacros;
1523 case MO_MACROS_HELO:
1525 macros = MilterHeloMacros;
1528 case MO_MACROS_ENVFROM:
1530 macros = MilterEnvFromMacros;
1533 case MO_MACROS_ENVRCPT:
1535 macros = MilterEnvRcptMacros;
1540 macros = MilterEOMMacros;
1543 case MO_MACROS_DATA:
1545 macros = MilterDataMacros;
1552 /* Skip leading commas, spaces */
1553 while (*p != '\0' &&
1554 (*p == ',' || (isascii(*p) && isspace(*p))))
1560 /* Find end of macro */
1562 while (*p != '\0' && *p != ',' &&
1563 isascii(*p) && !isspace(*p))
1568 if (nummac >= MAXFILTERMACROS)
1570 syserr("milter_set_option: too many macros in Milter.%s (max %d)",
1571 name, MAXFILTERMACROS);
1572 macros[nummac] = NULL;
1575 macros[nummac++] = macro;
1577 macros[nummac] = NULL;
1581 syserr("milter_set_option: invalid Milter option %s", name);
1585 setbitn(mo->mo_code, StickyMilterOpt);
1588 ** MILTER_REOPEN_DF -- open & truncate the data file (for replbody)
1591 ** e -- current envelope.
1594 ** 0 if succesful, -1 otherwise
1601 char dfname[MAXPATHLEN];
1603 (void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), sizeof dfname);
1606 ** In SuperSafe == SAFE_REALLY mode, e->e_dfp is a read-only FP so
1607 ** close and reopen writable (later close and reopen
1608 ** read only again).
1610 ** In SuperSafe != SAFE_REALLY mode, e->e_dfp still points at the
1611 ** buffered file I/O descriptor, still open for writing so there
1612 ** isn't any work to do here (except checking for consistency).
1615 if (SuperSafe == SAFE_REALLY)
1617 /* close read-only data file */
1618 if (bitset(EF_HAS_DF, e->e_flags) && e->e_dfp != NULL)
1620 (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT);
1621 e->e_flags &= ~EF_HAS_DF;
1625 if ((e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname,
1626 SM_IO_RDWR_B, NULL)) == NULL)
1628 MILTER_DF_ERROR("milter_reopen_df: sm_io_open %s: %s");
1632 else if (e->e_dfp == NULL)
1634 /* shouldn't happen */
1636 MILTER_DF_ERROR("milter_reopen_df: NULL e_dfp (%s: %s)");
1642 ** MILTER_RESET_DF -- re-open read-only the data file (for replbody)
1645 ** e -- current envelope.
1648 ** 0 if succesful, -1 otherwise
1656 char dfname[MAXPATHLEN];
1658 (void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), sizeof dfname);
1660 if (sm_io_flush(e->e_dfp, SM_TIME_DEFAULT) != 0 ||
1661 sm_io_error(e->e_dfp))
1663 MILTER_DF_ERROR("milter_reset_df: error writing/flushing %s: %s");
1666 else if (SuperSafe != SAFE_REALLY)
1668 /* skip next few clauses */
1671 else if ((afd = sm_io_getinfo(e->e_dfp, SM_IO_WHAT_FD, NULL)) >= 0
1674 MILTER_DF_ERROR("milter_reset_df: error sync'ing %s: %s");
1677 else if (sm_io_close(e->e_dfp, SM_TIME_DEFAULT) < 0)
1679 MILTER_DF_ERROR("milter_reset_df: error closing %s: %s");
1682 else if ((e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname,
1683 SM_IO_RDONLY_B, NULL)) == NULL)
1685 MILTER_DF_ERROR("milter_reset_df: error reopening %s: %s");
1689 e->e_flags |= EF_HAS_DF;
1693 ** MILTER_CAN_DELRCPTS -- can any milter filters delete recipients?
1699 ** true if any filter deletes recipients, false otherwise
1703 milter_can_delrcpts()
1709 sm_dprintf("milter_can_delrcpts:");
1711 for (i = 0; InputFilters[i] != NULL; i++)
1713 struct milter *m = InputFilters[i];
1715 if (bitset(SMFIF_DELRCPT, m->mf_fflags))
1722 sm_dprintf("%s\n", can ? "true" : "false");
1727 ** MILTER_QUIT_FILTER -- close down a single filter
1730 ** m -- milter structure of filter to close down.
1731 ** e -- current envelope.
1738 milter_quit_filter(m, e)
1743 sm_dprintf("milter_quit_filter(%s)\n", m->mf_name);
1744 if (MilterLogLevel > 18)
1745 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): quit filter",
1748 /* Never replace error state */
1749 if (m->mf_state == SMFS_ERROR)
1752 if (m->mf_sock < 0 ||
1753 m->mf_state == SMFS_CLOSED ||
1754 m->mf_state == SMFS_READY)
1757 m->mf_state = SMFS_CLOSED;
1761 (void) milter_write(m, SMFIC_QUIT, (char *) NULL, 0,
1762 m->mf_timeout[SMFTO_WRITE], e);
1763 if (m->mf_sock >= 0)
1765 (void) close(m->mf_sock);
1768 if (m->mf_state != SMFS_ERROR)
1769 m->mf_state = SMFS_CLOSED;
1772 ** MILTER_ABORT_FILTER -- tell filter to abort current message
1775 ** m -- milter structure of filter to abort.
1776 ** e -- current envelope.
1783 milter_abort_filter(m, e)
1788 sm_dprintf("milter_abort_filter(%s)\n", m->mf_name);
1789 if (MilterLogLevel > 10)
1790 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): abort filter",
1793 if (m->mf_sock < 0 ||
1794 m->mf_state != SMFS_INMSG)
1797 (void) milter_write(m, SMFIC_ABORT, (char *) NULL, 0,
1798 m->mf_timeout[SMFTO_WRITE], e);
1799 if (m->mf_state != SMFS_ERROR)
1800 m->mf_state = SMFS_DONE;
1803 ** MILTER_SEND_MACROS -- provide macros to the filters
1806 ** m -- milter to send macros to.
1807 ** macros -- macros to send for filter smfi_getsymval().
1808 ** cmd -- which command the macros are associated with.
1809 ** e -- current envelope (for macro access).
1816 milter_send_macros(m, macros, cmd, e)
1830 if (macros == NULL || macros[0] == NULL)
1833 /* put together data */
1834 s = 1; /* for the command character */
1835 for (i = 0; macros[i] != NULL; i++)
1837 mid = macid(macros[i]);
1840 v = macvalue(mid, e);
1843 expand(v, exp, sizeof(exp), e);
1844 s += strlen(macros[i]) + 1 + strlen(exp) + 1;
1850 buf = (char *) xalloc(s);
1853 for (i = 0; macros[i] != NULL; i++)
1855 mid = macid(macros[i]);
1858 v = macvalue(mid, e);
1861 expand(v, exp, sizeof(exp), e);
1864 sm_dprintf("milter_send_macros(%s, %c): %s=%s\n",
1865 m->mf_name, cmd, macros[i], exp);
1867 (void) sm_strlcpy(bp, macros[i], s - (bp - buf));
1868 bp += strlen(bp) + 1;
1869 (void) sm_strlcpy(bp, exp, s - (bp - buf));
1870 bp += strlen(bp) + 1;
1872 (void) milter_write(m, SMFIC_MACRO, buf, s,
1873 m->mf_timeout[SMFTO_WRITE], e);
1878 ** MILTER_SEND_COMMAND -- send a command and return the response for a filter
1881 ** m -- current milter filter
1882 ** command -- command to send.
1883 ** data -- optional command data.
1884 ** sz -- length of buf.
1885 ** e -- current envelope (for e->e_id).
1886 ** state -- return state word.
1889 ** response string (may be NULL)
1893 milter_send_command(m, command, data, sz, e, state)
1903 unsigned long skipflag;
1904 #if _FFR_MILTER_NOHDR_RESP
1905 unsigned long norespflag = 0;
1906 #endif /* _FFR_MILTER_NOHDR_RESP */
1912 sm_dprintf("milter_send_command(%s): cmd %c len %ld\n",
1913 m->mf_name, (char) command, (long) sz);
1915 /* find skip flag and default failure */
1919 skipflag = SMFIP_NOCONNECT;
1921 defresponse = "554 Command rejected";
1925 skipflag = SMFIP_NOHELO;
1927 defresponse = "550 Command rejected";
1931 skipflag = SMFIP_NOMAIL;
1933 defresponse = "550 5.7.1 Command rejected";
1937 skipflag = SMFIP_NORCPT;
1939 defresponse = "550 5.7.1 Command rejected";
1943 skipflag = SMFIP_NOHDRS;
1944 #if _FFR_MILTER_NOHDR_RESP
1945 norespflag = SMFIP_NOHREPL;
1946 #endif /* _FFR_MILTER_NOHDR_RESP */
1948 defresponse = "550 5.7.1 Command rejected";
1952 skipflag = SMFIP_NOBODY;
1954 defresponse = "554 5.7.1 Command rejected";
1958 skipflag = SMFIP_NOEOH;
1960 defresponse = "550 5.7.1 Command rejected";
1963 #if SMFI_VERSION > 2
1966 defresponse = "550 5.7.1 Command rejected";
1968 #endif /* SMFI_VERSION > 2 */
1975 /* NOTE: not handled by milter_send_command() */
1981 defresponse = "550 5.7.1 Command rejected";
1985 /* check if filter wants this command */
1986 if (skipflag != 0 &&
1987 bitset(skipflag, m->mf_pflags))
1990 /* send the command to the filter */
1991 (void) milter_write(m, command, data, sz,
1992 m->mf_timeout[SMFTO_WRITE], e);
1993 if (m->mf_state == SMFS_ERROR)
1995 MILTER_CHECK_ERROR(false, return NULL);
1999 #if _FFR_MILTER_NOHDR_RESP
2000 /* check if filter sends response to this command */
2001 if (norespflag != 0 && bitset(norespflag, m->mf_pflags))
2003 #endif /* _FFR_MILTER_NOHDR_RESP */
2005 /* get the response from the filter */
2006 response = milter_read(m, &rcmd, &rlen,
2007 m->mf_timeout[SMFTO_READ], e);
2008 if (m->mf_state == SMFS_ERROR)
2010 MILTER_CHECK_ERROR(false, return NULL);
2015 sm_dprintf("milter_send_command(%s): returned %c\n",
2016 m->mf_name, (char) rcmd);
2020 case SMFIR_REPLYCODE:
2021 MILTER_CHECK_REPLYCODE(defresponse);
2022 if (MilterLogLevel > 10)
2023 sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, reject=%s",
2024 m->mf_name, action, response);
2029 if (MilterLogLevel > 10)
2030 sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, reject",
2031 m->mf_name, action);
2036 if (MilterLogLevel > 10)
2037 sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, discard",
2038 m->mf_name, action);
2042 case SMFIR_TEMPFAIL:
2043 if (MilterLogLevel > 10)
2044 sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, tempfail",
2045 m->mf_name, action);
2050 /* this filter is done with message/connection */
2051 if (command == SMFIC_HELO ||
2052 command == SMFIC_CONNECT)
2053 m->mf_state = SMFS_CLOSABLE;
2055 m->mf_state = SMFS_DONE;
2056 if (MilterLogLevel > 10)
2057 sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, accepted",
2058 m->mf_name, action);
2061 case SMFIR_CONTINUE:
2062 /* if MAIL command is ok, filter is in message state */
2063 if (command == SMFIC_MAIL)
2064 m->mf_state = SMFS_INMSG;
2065 if (MilterLogLevel > 12)
2066 sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, continue",
2067 m->mf_name, action);
2071 /* Invalid response to command */
2072 if (MilterLogLevel > 0)
2073 sm_syslog(LOG_ERR, e->e_id,
2074 "milter_send_command(%s): action=%s returned bogus response %c",
2075 m->mf_name, action, rcmd);
2080 if (*state != SMFIR_REPLYCODE &&
2083 sm_free(response); /* XXX */
2090 ** MILTER_COMMAND -- send a command and return the response for each filter
2093 ** command -- command to send.
2094 ** data -- optional command data.
2095 ** sz -- length of buf.
2096 ** macros -- macros to send for filter smfi_getsymval().
2097 ** e -- current envelope (for macro access).
2098 ** state -- return state word.
2101 ** response string (may be NULL)
2105 milter_command(command, data, sz, macros, e, state)
2114 char *response = NULL;
2118 sm_dprintf("milter_command: cmd %c len %ld\n",
2119 (char) command, (long) sz);
2121 *state = SMFIR_CONTINUE;
2122 for (i = 0; InputFilters[i] != NULL; i++)
2124 struct milter *m = InputFilters[i];
2126 /* previous problem? */
2127 if (m->mf_state == SMFS_ERROR)
2129 MILTER_CHECK_ERROR(false, continue);
2134 if (m->mf_sock < 0 ||
2135 (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG))
2138 /* send macros (regardless of whether we send command) */
2139 if (macros != NULL && macros[0] != NULL)
2141 milter_send_macros(m, macros, command, e);
2142 if (m->mf_state == SMFS_ERROR)
2144 MILTER_CHECK_ERROR(false, continue);
2149 if (MilterLogLevel > 21)
2152 response = milter_send_command(m, command, data, sz, e, state);
2154 if (MilterLogLevel > 21)
2156 /* log the time it took for the command per filter */
2157 sm_syslog(LOG_INFO, e->e_id,
2158 "Milter (%s): time command (%c), %d",
2159 m->mf_name, command, (int) (tn - curtime()));
2162 if (*state != SMFIR_CONTINUE)
2168 ** MILTER_NEGOTIATE -- get version and flags from filter
2171 ** m -- milter filter structure.
2172 ** e -- current envelope.
2175 ** 0 on success, -1 otherwise
2179 milter_negotiate(m, e)
2189 char data[MILTER_OPTLEN];
2192 if (m->mf_sock < 0 || m->mf_state != SMFS_OPEN)
2194 if (MilterLogLevel > 0)
2195 sm_syslog(LOG_ERR, e->e_id,
2196 "Milter (%s): negotiate, impossible state",
2202 fvers = htonl(SMFI_VERSION);
2203 fflags = htonl(SMFI_CURR_ACTS);
2204 pflags = htonl(SMFI_CURR_PROT);
2205 (void) memcpy(data, (char *) &fvers, MILTER_LEN_BYTES);
2206 (void) memcpy(data + MILTER_LEN_BYTES,
2207 (char *) &fflags, MILTER_LEN_BYTES);
2208 (void) memcpy(data + (MILTER_LEN_BYTES * 2),
2209 (char *) &pflags, MILTER_LEN_BYTES);
2210 (void) milter_write(m, SMFIC_OPTNEG, data, sizeof data,
2211 m->mf_timeout[SMFTO_WRITE], e);
2213 if (m->mf_state == SMFS_ERROR)
2216 response = milter_read(m, &rcmd, &rlen, m->mf_timeout[SMFTO_READ], e);
2217 if (m->mf_state == SMFS_ERROR)
2220 if (rcmd != SMFIC_OPTNEG)
2223 sm_dprintf("milter_negotiate(%s): returned %c instead of %c\n",
2224 m->mf_name, rcmd, SMFIC_OPTNEG);
2225 if (MilterLogLevel > 0)
2226 sm_syslog(LOG_ERR, e->e_id,
2227 "Milter (%s): negotiate: returned %c instead of %c",
2228 m->mf_name, rcmd, SMFIC_OPTNEG);
2229 if (response != NULL)
2230 sm_free(response); /* XXX */
2235 /* Make sure we have enough bytes for the version */
2236 if (response == NULL || rlen < MILTER_LEN_BYTES)
2239 sm_dprintf("milter_negotiate(%s): did not return valid info\n",
2241 if (MilterLogLevel > 0)
2242 sm_syslog(LOG_ERR, e->e_id,
2243 "Milter (%s): negotiate: did not return valid info",
2245 if (response != NULL)
2246 sm_free(response); /* XXX */
2251 /* extract information */
2252 (void) memcpy((char *) &fvers, response, MILTER_LEN_BYTES);
2254 /* Now make sure we have enough for the feature bitmap */
2255 if (rlen != MILTER_OPTLEN)
2258 sm_dprintf("milter_negotiate(%s): did not return enough info\n",
2260 if (MilterLogLevel > 0)
2261 sm_syslog(LOG_ERR, e->e_id,
2262 "Milter (%s): negotiate: did not return enough info",
2264 if (response != NULL)
2265 sm_free(response); /* XXX */
2270 (void) memcpy((char *) &fflags, response + MILTER_LEN_BYTES,
2272 (void) memcpy((char *) &pflags, response + (MILTER_LEN_BYTES * 2),
2274 sm_free(response); /* XXX */
2277 m->mf_fvers = ntohl(fvers);
2278 m->mf_fflags = ntohl(fflags);
2279 m->mf_pflags = ntohl(pflags);
2281 /* check for version compatibility */
2282 if (m->mf_fvers == 1 ||
2283 m->mf_fvers > SMFI_VERSION)
2286 sm_dprintf("milter_negotiate(%s): version %d != MTA milter version %d\n",
2287 m->mf_name, m->mf_fvers, SMFI_VERSION);
2288 if (MilterLogLevel > 0)
2289 sm_syslog(LOG_ERR, e->e_id,
2290 "Milter (%s): negotiate: version %d != MTA milter version %d",
2291 m->mf_name, m->mf_fvers, SMFI_VERSION);
2296 /* check for filter feature mismatch */
2297 if ((m->mf_fflags & SMFI_CURR_ACTS) != m->mf_fflags)
2300 sm_dprintf("milter_negotiate(%s): filter abilities 0x%x != MTA milter abilities 0x%lx\n",
2301 m->mf_name, m->mf_fflags,
2303 if (MilterLogLevel > 0)
2304 sm_syslog(LOG_ERR, e->e_id,
2305 "Milter (%s): negotiate: filter abilities 0x%x != MTA milter abilities 0x%lx",
2306 m->mf_name, m->mf_fflags,
2307 (unsigned long) SMFI_CURR_ACTS);
2312 /* check for protocol feature mismatch */
2313 if ((m->mf_pflags & SMFI_CURR_PROT) != m->mf_pflags)
2316 sm_dprintf("milter_negotiate(%s): protocol abilities 0x%x != MTA milter abilities 0x%lx\n",
2317 m->mf_name, m->mf_pflags,
2318 (unsigned long) SMFI_CURR_PROT);
2319 if (MilterLogLevel > 0)
2320 sm_syslog(LOG_ERR, e->e_id,
2321 "Milter (%s): negotiate: protocol abilities 0x%x != MTA milter abilities 0x%lx",
2322 m->mf_name, m->mf_pflags,
2323 (unsigned long) SMFI_CURR_PROT);
2329 sm_dprintf("milter_negotiate(%s): version %u, fflags 0x%x, pflags 0x%x\n",
2330 m->mf_name, m->mf_fvers, m->mf_fflags, m->mf_pflags);
2334 ** MILTER_PER_CONNECTION_CHECK -- checks on per-connection commands
2336 ** Reduce code duplication by putting these checks in one place
2339 ** e -- current envelope.
2346 milter_per_connection_check(e)
2351 /* see if we are done with any of the filters */
2352 for (i = 0; InputFilters[i] != NULL; i++)
2354 struct milter *m = InputFilters[i];
2356 if (m->mf_state == SMFS_CLOSABLE)
2357 milter_quit_filter(m, e);
2361 ** MILTER_ERROR -- Put a milter filter into error state
2364 ** m -- the broken filter.
2365 ** e -- current envelope.
2377 ** We could send a quit here but we may have gotten here due to
2378 ** an I/O error so we don't want to try to make things worse.
2381 if (m->mf_sock >= 0)
2383 (void) close(m->mf_sock);
2386 m->mf_state = SMFS_ERROR;
2388 if (MilterLogLevel > 0)
2389 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): to error state",
2393 ** MILTER_HEADERS -- send headers to a single milter filter
2396 ** m -- current filter.
2397 ** e -- current envelope.
2398 ** state -- return state from response.
2401 ** response string (may be NULL)
2405 milter_headers(m, e, state)
2410 char *response = NULL;
2413 if (MilterLogLevel > 17)
2414 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): headers, send",
2417 for (h = e->e_header; h != NULL; h = h->h_link)
2422 /* don't send over deleted headers */
2423 if (h->h_value == NULL)
2425 /* strip H_USER so not counted in milter_changeheader() */
2426 h->h_flags &= ~H_USER;
2430 /* skip auto-generated */
2431 if (!bitset(H_USER, h->h_flags))
2435 sm_dprintf("milter_headers: %s: %s\n",
2436 h->h_field, h->h_value);
2437 if (MilterLogLevel > 21)
2438 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): header, %s",
2439 m->mf_name, h->h_field);
2441 s = strlen(h->h_field) + 1 + strlen(h->h_value) + 1;
2444 buf = (char *) xalloc(s);
2445 (void) sm_snprintf(buf, s, "%s%c%s",
2446 h->h_field, '\0', h->h_value);
2449 response = milter_send_command(m, SMFIC_HEADER, buf,
2451 sm_free(buf); /* XXX */
2452 if (m->mf_state == SMFS_ERROR ||
2453 m->mf_state == SMFS_DONE ||
2454 *state != SMFIR_CONTINUE)
2457 if (MilterLogLevel > 17)
2458 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): headers, sent",
2463 ** MILTER_BODY -- send the body to a filter
2466 ** m -- current filter.
2467 ** e -- current envelope.
2468 ** state -- return state from response.
2471 ** response string (may be NULL)
2475 milter_body(m, e, state)
2480 char bufchar = '\0';
2481 char prevchar = '\0';
2483 char *response = NULL;
2485 char buf[MILTER_CHUNK_SIZE];
2488 sm_dprintf("milter_body\n");
2490 if (bfrewind(e->e_dfp) < 0)
2492 ExitStat = EX_IOERR;
2493 *state = SMFIR_TEMPFAIL;
2494 syserr("milter_body: %s/%cf%s: rewind error",
2495 qid_printqueue(e->e_qgrp, e->e_qdir),
2496 DATAFL_LETTER, e->e_id);
2500 if (MilterLogLevel > 17)
2501 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): body, send",
2504 while ((c = sm_io_getc(e->e_dfp, SM_TIME_DEFAULT)) != SM_IO_EOF)
2506 /* Change LF to CRLF */
2509 /* Not a CRLF already? */
2510 if (prevchar != '\r')
2512 /* Room for CR now? */
2513 if (bp + 2 > &buf[sizeof buf])
2515 /* No room, buffer LF */
2518 /* and send CR now */
2523 /* Room to do it now */
2531 if (bp >= &buf[sizeof buf])
2534 response = milter_send_command(m, SMFIC_BODY, buf,
2535 bp - buf, e, state);
2537 if (bufchar != '\0')
2544 if (m->mf_state == SMFS_ERROR ||
2545 m->mf_state == SMFS_DONE ||
2546 *state != SMFIR_CONTINUE)
2550 /* check for read errors */
2551 if (sm_io_error(e->e_dfp))
2553 ExitStat = EX_IOERR;
2554 if (*state == SMFIR_CONTINUE ||
2555 *state == SMFIR_ACCEPT)
2557 *state = SMFIR_TEMPFAIL;
2558 if (response != NULL)
2560 sm_free(response); /* XXX */
2564 syserr("milter_body: %s/%cf%s: read error",
2565 qid_printqueue(e->e_qgrp, e->e_qdir),
2566 DATAFL_LETTER, e->e_id);
2570 /* send last body chunk */
2572 m->mf_state != SMFS_ERROR &&
2573 m->mf_state != SMFS_DONE &&
2574 *state == SMFIR_CONTINUE)
2577 response = milter_send_command(m, SMFIC_BODY, buf, bp - buf,
2581 if (MilterLogLevel > 17)
2582 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): body, sent",
2592 ** MILTER_ADDHEADER -- Add the supplied header to the message
2595 ** response -- encoded form of header/value.
2596 ** rlen -- length of response.
2597 ** e -- current envelope.
2604 milter_addheader(response, rlen, e)
2613 sm_dprintf("milter_addheader: ");
2616 if (response == NULL)
2619 sm_dprintf("NULL response\n");
2623 if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen)
2626 sm_dprintf("didn't follow protocol (total len)\n");
2630 /* Find separating NUL */
2631 val = response + strlen(response) + 1;
2633 /* another sanity check */
2634 if (strlen(response) + strlen(val) + 2 != (size_t) rlen)
2637 sm_dprintf("didn't follow protocol (part len)\n");
2641 if (*response == '\0')
2644 sm_dprintf("empty field name\n");
2648 for (h = e->e_header; h != NULL; h = h->h_link)
2650 if (sm_strcasecmp(h->h_field, response) == 0 &&
2651 !bitset(H_USER, h->h_flags) &&
2652 !bitset(H_TRACE, h->h_flags))
2656 /* add to e_msgsize */
2657 e->e_msgsize += strlen(response) + 2 + strlen(val);
2662 sm_dprintf("Replace default header %s value with %s\n",
2664 if (MilterLogLevel > 8)
2665 sm_syslog(LOG_INFO, e->e_id,
2666 "Milter change: default header %s value with %s",
2668 h->h_value = newstr(val);
2669 h->h_flags |= H_USER;
2674 sm_dprintf("Add %s: %s\n", response, val);
2675 if (MilterLogLevel > 8)
2676 sm_syslog(LOG_INFO, e->e_id, "Milter add: header: %s: %s",
2678 addheader(newstr(response), val, H_USER, e);
2682 ** MILTER_INSHEADER -- Insert the supplied header
2685 ** response -- encoded form of header/value.
2686 ** rlen -- length of response.
2687 ** e -- current envelope.
2693 ** Unlike milter_addheader(), this does not attempt to determine
2694 ** if the header already exists in the envelope, even a
2695 ** deleted version. It just blindly inserts.
2699 milter_insheader(response, rlen, e)
2709 sm_dprintf("milter_insheader: ");
2712 if (response == NULL)
2715 sm_dprintf("NULL response\n");
2719 if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen)
2722 sm_dprintf("didn't follow protocol (total len)\n");
2727 (void) memcpy((char *) &i, response, MILTER_LEN_BYTES);
2729 field = response + MILTER_LEN_BYTES;
2730 val = field + strlen(field) + 1;
2732 /* another sanity check */
2733 if (MILTER_LEN_BYTES + strlen(field) + 1 +
2734 strlen(val) + 1 != (size_t) rlen)
2737 sm_dprintf("didn't follow protocol (part len)\n");
2744 sm_dprintf("empty field name\n");
2748 /* add to e_msgsize */
2749 e->e_msgsize += strlen(response) + 2 + strlen(val);
2752 sm_dprintf("Insert (%d) %s: %s\n", idx, response, val);
2753 if (MilterLogLevel > 8)
2754 sm_syslog(LOG_INFO, e->e_id,
2755 "Milter insert (%d): header: %s: %s",
2757 insheader(idx, newstr(field), val, H_USER, e);
2760 ** MILTER_CHANGEHEADER -- Change the supplied header in the message
2763 ** response -- encoded form of header/index/value.
2764 ** rlen -- length of response.
2765 ** e -- current envelope.
2772 milter_changeheader(response, rlen, e)
2782 sm_dprintf("milter_changeheader: ");
2785 if (response == NULL)
2788 sm_dprintf("NULL response\n");
2792 if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen)
2795 sm_dprintf("didn't follow protocol (total len)\n");
2799 /* Find separating NUL */
2800 (void) memcpy((char *) &i, response, MILTER_LEN_BYTES);
2802 field = response + MILTER_LEN_BYTES;
2803 val = field + strlen(field) + 1;
2805 /* another sanity check */
2806 if (MILTER_LEN_BYTES + strlen(field) + 1 +
2807 strlen(val) + 1 != (size_t) rlen)
2810 sm_dprintf("didn't follow protocol (part len)\n");
2817 sm_dprintf("empty field name\n");
2822 for (h = e->e_header; h != NULL; h = h->h_link)
2824 if (sm_strcasecmp(h->h_field, field) == 0)
2826 if (bitset(H_USER, h->h_flags) &&
2832 else if (!bitset(H_USER, h->h_flags) &&
2833 !bitset(H_TRACE, h->h_flags))
2836 ** DRUMS msg-fmt draft says can only have
2837 ** multiple occurences of trace fields,
2838 ** so make sure we replace any non-trace,
2847 /* if not found as user-provided header at index, use sysheader */
2856 sm_dprintf("Delete (noop) %s\n", field);
2857 if (MilterLogLevel > 8)
2858 sm_syslog(LOG_INFO, e->e_id,
2859 "Milter delete (noop): header: %s"
2864 /* treat modify value with no existing header as add */
2866 sm_dprintf("Add %s: %s\n", field, val);
2867 if (MilterLogLevel > 8)
2868 sm_syslog(LOG_INFO, e->e_id,
2869 "Milter change (add): header: %s: %s"
2871 addheader(newstr(field), val, H_USER, e);
2880 sm_dprintf("Delete%s %s: %s\n",
2881 h == sysheader ? " (default header)" : "",
2883 h->h_value == NULL ? "<NULL>" : h->h_value);
2887 sm_dprintf("Change%s %s: from %s to %s\n",
2888 h == sysheader ? " (default header)" : "",
2890 h->h_value == NULL ? "<NULL>" : h->h_value,
2895 if (MilterLogLevel > 8)
2899 sm_syslog(LOG_INFO, e->e_id,
2900 "Milter delete: header%s %s: %s",
2901 h == sysheader ? " (default header)" : "",
2903 h->h_value == NULL ? "<NULL>" : h->h_value);
2907 sm_syslog(LOG_INFO, e->e_id,
2908 "Milter change: header%s %s: from %s to %s",
2909 h == sysheader ? " (default header)" : "",
2911 h->h_value == NULL ? "<NULL>" : h->h_value,
2916 if (h != sysheader && h->h_value != NULL)
2920 l = strlen(h->h_value);
2921 if (l > e->e_msgsize)
2925 /* rpool, don't free: sm_free(h->h_value); XXX */
2930 /* Remove "Field: " from message size */
2935 l = strlen(h->h_field) + 2;
2936 if (l > e->e_msgsize)
2945 h->h_value = newstr(val);
2946 h->h_flags |= H_USER;
2947 e->e_msgsize += strlen(h->h_value);
2951 ** MILTER_ADDRCPT -- Add the supplied recipient to the message
2954 ** response -- encoded form of recipient address.
2955 ** rlen -- length of response.
2956 ** e -- current envelope.
2963 milter_addrcpt(response, rlen, e)
2971 sm_dprintf("milter_addrcpt: ");
2974 if (response == NULL)
2977 sm_dprintf("NULL response\n");
2981 if (*response == '\0' ||
2982 strlen(response) + 1 != (size_t) rlen)
2985 sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n",
2986 (int) strlen(response), (int) (rlen - 1));
2991 sm_dprintf("%s\n", response);
2992 if (MilterLogLevel > 8)
2993 sm_syslog(LOG_INFO, e->e_id, "Milter add: rcpt: %s", response);
2995 (void) sendtolist(response, NULLADDR, &e->e_sendqueue, 0, e);
3000 ** MILTER_DELRCPT -- Delete the supplied recipient from the message
3003 ** response -- encoded form of recipient address.
3004 ** rlen -- length of response.
3005 ** e -- current envelope.
3012 milter_delrcpt(response, rlen, e)
3018 sm_dprintf("milter_delrcpt: ");
3021 if (response == NULL)
3024 sm_dprintf("NULL response\n");
3028 if (*response == '\0' ||
3029 strlen(response) + 1 != (size_t) rlen)
3032 sm_dprintf("didn't follow protocol (total len)\n");
3037 sm_dprintf("%s\n", response);
3038 if (MilterLogLevel > 8)
3039 sm_syslog(LOG_INFO, e->e_id, "Milter delete: rcpt %s",
3041 (void) removefromlist(response, &e->e_sendqueue, e);
3045 ** MILTER_REPLBODY -- Replace the current data file with new body
3048 ** response -- encoded form of new body.
3049 ** rlen -- length of response.
3050 ** newfilter -- if first time called by a new filter
3051 ** e -- current envelope.
3054 ** 0 upon success, -1 upon failure
3058 milter_replbody(response, rlen, newfilter, e)
3064 static char prevchar;
3068 sm_dprintf("milter_replbody\n");
3070 /* If a new filter, reset previous character and truncate data file */
3074 char dfname[MAXPATHLEN];
3076 (void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER),
3079 /* Reset prevchar */
3082 /* Get the current data file information */
3083 prevsize = sm_io_getinfo(e->e_dfp, SM_IO_WHAT_SIZE, NULL);
3087 /* truncate current data file */
3088 if (sm_io_getinfo(e->e_dfp, SM_IO_WHAT_ISTYPE, BF_FILE_TYPE))
3090 if (sm_io_setinfo(e->e_dfp, SM_BF_TRUNCATE, NULL) < 0)
3092 MILTER_DF_ERROR("milter_replbody: sm_io truncate %s: %s");
3100 err = sm_io_error(e->e_dfp);
3101 (void) sm_io_flush(e->e_dfp, SM_TIME_DEFAULT);
3104 ** Clear error if tried to fflush()
3105 ** a read-only file pointer and
3106 ** there wasn't a previous error.
3110 sm_io_clearerr(e->e_dfp);
3112 /* errno is set implicitly by fseek() before return */
3113 err = sm_io_seek(e->e_dfp, SM_TIME_DEFAULT,
3117 MILTER_DF_ERROR("milter_replbody: sm_io_seek %s: %s");
3121 /* XXX: Not much we can do except rewind it */
3123 MILTER_DF_ERROR("milter_replbody: ftruncate not available on this platform (%s:%s)");
3125 # else /* NOFTRUNCATE */
3126 err = ftruncate(sm_io_getinfo(e->e_dfp,
3127 SM_IO_WHAT_FD, NULL),
3131 MILTER_DF_ERROR("milter_replbody: sm_io ftruncate %s: %s");
3134 # endif /* NOFTRUNCATE */
3137 if (prevsize > e->e_msgsize)
3140 e->e_msgsize -= prevsize;
3143 if (newfilter && MilterLogLevel > 8)
3144 sm_syslog(LOG_INFO, e->e_id, "Milter message: body replaced");
3146 if (response == NULL)
3148 /* Flush the buffered '\r' */
3149 if (prevchar == '\r')
3151 (void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT, prevchar);
3157 for (i = 0; i < rlen; i++)
3159 /* Buffered char from last chunk */
3160 if (i == 0 && prevchar == '\r')
3162 /* Not CRLF, output prevchar */
3163 if (response[i] != '\n')
3165 (void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT,
3172 /* Turn CRLF into LF */
3173 if (response[i] == '\r')
3175 /* check if at end of chunk */
3178 /* If LF, strip CR */
3179 if (response[i + 1] == '\n')
3184 /* check next chunk */
3189 (void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT, response[i]);
3200 ** MILTER_INIT -- open and negotiate with all of the filters
3203 ** e -- current envelope.
3204 ** state -- return state from response.
3207 ** true iff at least one filter is active
3212 milter_init(e, state)
3219 sm_dprintf("milter_init\n");
3221 *state = SMFIR_CONTINUE;
3222 if (InputFilters[0] == NULL)
3224 if (MilterLogLevel > 10)
3225 sm_syslog(LOG_INFO, e->e_id,
3226 "Milter: no active filter");
3230 for (i = 0; InputFilters[i] != NULL; i++)
3232 struct milter *m = InputFilters[i];
3234 m->mf_sock = milter_open(m, false, e);
3235 if (m->mf_state == SMFS_ERROR)
3237 MILTER_CHECK_ERROR(true, continue);
3241 if (m->mf_sock < 0 ||
3242 milter_negotiate(m, e) < 0 ||
3243 m->mf_state == SMFS_ERROR)
3246 sm_dprintf("milter_init(%s): failed to %s\n",
3248 m->mf_sock < 0 ? "open" :
3250 if (MilterLogLevel > 0)
3251 sm_syslog(LOG_ERR, e->e_id,
3252 "Milter (%s): init failed to %s",
3254 m->mf_sock < 0 ? "open" :
3257 /* if negotation failure, close socket */
3259 MILTER_CHECK_ERROR(true, continue);
3262 if (MilterLogLevel > 9)
3263 sm_syslog(LOG_INFO, e->e_id,
3264 "Milter (%s): init success to %s",
3266 m->mf_sock < 0 ? "open" : "negotiate");
3270 ** If something temp/perm failed with one of the filters,
3271 ** we won't be using any of them, so clear any existing
3275 if (*state != SMFIR_CONTINUE)
3281 ** MILTER_CONNECT -- send connection info to milter filters
3284 ** hostname -- hostname of remote machine.
3285 ** addr -- address of remote machine.
3286 ** e -- current envelope.
3287 ** state -- return state from response.
3290 ** response string (may be NULL)
3294 milter_connect(hostname, addr, e, state)
3301 unsigned short port;
3304 char *sockinfo = NULL;
3307 char buf6[INET6_ADDRSTRLEN];
3308 # endif /* NETINET6 */
3311 sm_dprintf("milter_connect(%s)\n", hostname);
3312 if (MilterLogLevel > 9)
3313 sm_syslog(LOG_INFO, e->e_id, "Milter: connect to filters");
3316 switch (addr.sa.sa_family)
3320 family = SMFIA_UNIX;
3322 sockinfo = addr.sunix.sun_path;
3324 # endif /* NETUNIX */
3328 family = SMFIA_INET;
3329 port = addr.sin.sin_port;
3330 sockinfo = (char *) inet_ntoa(addr.sin.sin_addr);
3332 # endif /* NETINET */
3336 if (IN6_IS_ADDR_V4MAPPED(&addr.sin6.sin6_addr))
3337 family = SMFIA_INET;
3339 family = SMFIA_INET6;
3340 port = addr.sin6.sin6_port;
3341 sockinfo = anynet_ntop(&addr.sin6.sin6_addr, buf6,
3343 if (sockinfo == NULL)
3346 # endif /* NETINET6 */
3349 family = SMFIA_UNKNOWN;
3353 s = strlen(hostname) + 1 + sizeof(family);
3354 if (family != SMFIA_UNKNOWN)
3355 s += sizeof(port) + strlen(sockinfo) + 1;
3357 buf = (char *) xalloc(s);
3360 /* put together data */
3361 (void) memcpy(bp, hostname, strlen(hostname));
3362 bp += strlen(hostname);
3364 (void) memcpy(bp, &family, sizeof family);
3365 bp += sizeof family;
3366 if (family != SMFIA_UNKNOWN)
3368 (void) memcpy(bp, &port, sizeof port);
3371 /* include trailing '\0' */
3372 (void) memcpy(bp, sockinfo, strlen(sockinfo) + 1);
3375 response = milter_command(SMFIC_CONNECT, buf, s,
3376 MilterConnectMacros, e, state);
3377 sm_free(buf); /* XXX */
3380 ** If this message connection is done for,
3381 ** close the filters.
3384 if (*state != SMFIR_CONTINUE)
3386 if (MilterLogLevel > 9)
3387 sm_syslog(LOG_INFO, e->e_id, "Milter: connect, ending");
3391 milter_per_connection_check(e);
3394 ** SMFIR_REPLYCODE can't work with connect due to
3395 ** the requirements of SMTP. Therefore, ignore the
3396 ** reply code text but keep the state it would reflect.
3399 if (*state == SMFIR_REPLYCODE)
3401 if (response != NULL &&
3404 if (strncmp(response, "421 ", 4) == 0)
3405 *state = SMFIR_SHUTDOWN;
3407 *state = SMFIR_TEMPFAIL;
3410 *state = SMFIR_REJECT;
3411 if (response != NULL)
3413 sm_free(response); /* XXX */
3420 ** MILTER_HELO -- send SMTP HELO/EHLO command info to milter filters
3423 ** helo -- argument to SMTP HELO/EHLO command.
3424 ** e -- current envelope.
3425 ** state -- return state from response.
3428 ** response string (may be NULL)
3432 milter_helo(helo, e, state)
3441 sm_dprintf("milter_helo(%s)\n", helo);
3443 /* HELO/EHLO can come at any point */
3444 for (i = 0; InputFilters[i] != NULL; i++)
3446 struct milter *m = InputFilters[i];
3448 switch (m->mf_state)
3451 /* abort in message filters */
3452 milter_abort_filter(m, e);
3456 /* reset done filters */
3457 m->mf_state = SMFS_OPEN;
3462 response = milter_command(SMFIC_HELO, helo, strlen(helo) + 1,
3463 MilterHeloMacros, e, state);
3464 milter_per_connection_check(e);
3468 ** MILTER_ENVFROM -- send SMTP MAIL command info to milter filters
3471 ** args -- SMTP MAIL command args (args[0] == sender).
3472 ** e -- current envelope.
3473 ** state -- return state from response.
3476 ** response string (may be NULL)
3480 milter_envfrom(args, e, state)
3492 sm_dprintf("milter_envfrom:");
3493 for (i = 0; args[i] != NULL; i++)
3494 sm_dprintf(" %s", args[i]);
3499 if (args[0] == NULL)
3501 *state = SMFIR_REJECT;
3502 if (MilterLogLevel > 10)
3503 sm_syslog(LOG_INFO, e->e_id,
3504 "Milter: reject, no sender");
3508 /* new message, so ... */
3509 for (i = 0; InputFilters[i] != NULL; i++)
3511 struct milter *m = InputFilters[i];
3513 switch (m->mf_state)
3516 /* abort in message filters */
3517 milter_abort_filter(m, e);
3521 /* reset done filters */
3522 m->mf_state = SMFS_OPEN;
3527 /* put together data */
3529 for (i = 0; args[i] != NULL; i++)
3530 s += strlen(args[i]) + 1;
3534 *state = SMFIR_TEMPFAIL;
3538 buf = (char *) xalloc(s);
3540 for (i = 0; args[i] != NULL; i++)
3542 (void) sm_strlcpy(bp, args[i], s - (bp - buf));
3543 bp += strlen(bp) + 1;
3546 if (MilterLogLevel > 14)
3547 sm_syslog(LOG_INFO, e->e_id, "Milter: senders: %s", buf);
3550 response = milter_command(SMFIC_MAIL, buf, s,
3551 MilterEnvFromMacros, e, state);
3552 sm_free(buf); /* XXX */
3555 ** If filter rejects/discards a per message command,
3556 ** abort the other filters since we are done with the
3560 MILTER_CHECK_DONE_MSG();
3561 if (MilterLogLevel > 10 && *state == SMFIR_REJECT)
3562 sm_syslog(LOG_INFO, e->e_id, "Milter: reject, senders");
3567 ** MILTER_ENVRCPT -- send SMTP RCPT command info to milter filters
3570 ** args -- SMTP MAIL command args (args[0] == recipient).
3571 ** e -- current envelope.
3572 ** state -- return state from response.
3575 ** response string (may be NULL)
3579 milter_envrcpt(args, e, state)
3591 sm_dprintf("milter_envrcpt:");
3592 for (i = 0; args[i] != NULL; i++)
3593 sm_dprintf(" %s", args[i]);
3598 if (args[0] == NULL)
3600 *state = SMFIR_REJECT;
3601 if (MilterLogLevel > 10)
3602 sm_syslog(LOG_INFO, e->e_id, "Milter: reject, no rcpt");
3606 /* put together data */
3608 for (i = 0; args[i] != NULL; i++)
3609 s += strlen(args[i]) + 1;
3613 *state = SMFIR_TEMPFAIL;
3617 buf = (char *) xalloc(s);
3619 for (i = 0; args[i] != NULL; i++)
3621 (void) sm_strlcpy(bp, args[i], s - (bp - buf));
3622 bp += strlen(bp) + 1;
3625 if (MilterLogLevel > 14)
3626 sm_syslog(LOG_INFO, e->e_id, "Milter: rcpts: %s", buf);
3629 response = milter_command(SMFIC_RCPT, buf, s,
3630 MilterEnvRcptMacros, e, state);
3631 sm_free(buf); /* XXX */
3635 #if SMFI_VERSION > 3
3637 ** MILTER_DATA_CMD -- send SMTP DATA command info to milter filters
3640 ** e -- current envelope.
3641 ** state -- return state from response.
3644 ** response string (may be NULL)
3648 milter_data_cmd(e, state)
3653 sm_dprintf("milter_data_cmd\n");
3656 return milter_command(SMFIC_DATA, NULL, 0, MilterDataMacros, e, state);
3658 #endif /* SMFI_VERSION > 3 */
3661 ** MILTER_DATA -- send message headers/body and gather final message results
3664 ** e -- current envelope.
3665 ** state -- return state from response.
3668 ** response string (may be NULL)
3671 ** - Uses e->e_dfp for access to the body
3672 ** - Can call the various milter action routines to
3673 ** modify the envelope or message.
3676 # define MILTER_CHECK_RESULTS() \
3677 if (*state == SMFIR_ACCEPT || \
3678 m->mf_state == SMFS_DONE || \
3679 m->mf_state == SMFS_ERROR) \
3681 if (m->mf_state != SMFS_ERROR) \
3682 m->mf_state = SMFS_DONE; \
3683 continue; /* to next filter */ \
3685 if (*state != SMFIR_CONTINUE) \
3687 m->mf_state = SMFS_DONE; \
3692 milter_data(e, state)
3696 bool replbody = false; /* milter_replbody() called? */
3697 bool replfailed = false; /* milter_replbody() failed? */
3698 bool rewind = false; /* rewind data file? */
3699 bool dfopen = false; /* data file open for writing? */
3700 bool newfilter; /* reset on each new filter */
3704 char *response = NULL;
3709 sm_dprintf("milter_data\n");
3711 *state = SMFIR_CONTINUE;
3714 ** XXX: Should actually send body chunks to each filter
3715 ** a chunk at a time instead of sending the whole body to
3716 ** each filter in turn. However, only if the filters don't
3720 for (i = 0; InputFilters[i] != NULL; i++)
3722 struct milter *m = InputFilters[i];
3724 if (*state != SMFIR_CONTINUE &&
3725 *state != SMFIR_ACCEPT)
3728 ** A previous filter has dealt with the message,
3729 ** safe to stop processing the filters.
3735 /* Now reset state for later evaluation */
3736 *state = SMFIR_CONTINUE;
3739 /* previous problem? */
3740 if (m->mf_state == SMFS_ERROR)
3742 MILTER_CHECK_ERROR(false, continue);
3747 if (m->mf_sock < 0 ||
3748 (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG))
3751 m->mf_state = SMFS_INMSG;
3753 /* check if filter wants the headers */
3754 if (!bitset(SMFIP_NOHDRS, m->mf_pflags))
3756 response = milter_headers(m, e, state);
3757 MILTER_CHECK_RESULTS();
3760 /* check if filter wants EOH */
3761 if (!bitset(SMFIP_NOEOH, m->mf_pflags))
3764 sm_dprintf("milter_data: eoh\n");
3767 response = milter_send_command(m, SMFIC_EOH, NULL, 0,
3769 MILTER_CHECK_RESULTS();
3772 /* check if filter wants the body */
3773 if (!bitset(SMFIP_NOBODY, m->mf_pflags) &&
3777 response = milter_body(m, e, state);
3778 MILTER_CHECK_RESULTS();
3781 if (MilterEOMMacros[0] != NULL)
3783 milter_send_macros(m, MilterEOMMacros,
3785 MILTER_CHECK_RESULTS();
3788 /* send the final body chunk */
3789 (void) milter_write(m, SMFIC_BODYEOB, NULL, 0,
3790 m->mf_timeout[SMFTO_WRITE], e);
3792 /* Get time EOM sent for timeout */
3793 eomsent = curtime();
3795 /* deal with the possibility of multiple responses */
3796 while (*state == SMFIR_CONTINUE)
3798 /* Check total timeout from EOM to final ACK/NAK */
3799 if (m->mf_timeout[SMFTO_EOM] > 0 &&
3800 curtime() - eomsent >= m->mf_timeout[SMFTO_EOM])
3803 sm_dprintf("milter_data(%s): EOM ACK/NAK timeout\n",
3805 if (MilterLogLevel > 0)
3806 sm_syslog(LOG_ERR, e->e_id,
3807 "milter_data(%s): EOM ACK/NAK timeout",
3810 MILTER_CHECK_ERROR(false, break);
3814 response = milter_read(m, &rcmd, &rlen,
3815 m->mf_timeout[SMFTO_READ], e);
3816 if (m->mf_state == SMFS_ERROR)
3820 sm_dprintf("milter_data(%s): state %c\n",
3821 m->mf_name, (char) rcmd);
3825 case SMFIR_REPLYCODE:
3826 MILTER_CHECK_REPLYCODE("554 5.7.1 Command rejected");
3827 if (MilterLogLevel > 12)
3828 sm_syslog(LOG_INFO, e->e_id, "milter=%s, reject=%s",
3829 m->mf_name, response);
3831 m->mf_state = SMFS_DONE;
3834 case SMFIR_REJECT: /* log msg at end of function */
3835 if (MilterLogLevel > 12)
3836 sm_syslog(LOG_INFO, e->e_id, "milter=%s, reject",
3839 m->mf_state = SMFS_DONE;
3843 if (MilterLogLevel > 12)
3844 sm_syslog(LOG_INFO, e->e_id, "milter=%s, discard",
3847 m->mf_state = SMFS_DONE;
3850 case SMFIR_TEMPFAIL:
3851 if (MilterLogLevel > 12)
3852 sm_syslog(LOG_INFO, e->e_id, "milter=%s, tempfail",
3855 m->mf_state = SMFS_DONE;
3858 case SMFIR_CONTINUE:
3860 /* this filter is done with message */
3862 *state = SMFIR_TEMPFAIL;
3864 *state = SMFIR_ACCEPT;
3865 m->mf_state = SMFS_DONE;
3868 case SMFIR_PROGRESS:
3871 case SMFIR_QUARANTINE:
3872 if (!bitset(SMFIF_QUARANTINE, m->mf_fflags))
3874 if (MilterLogLevel > 9)
3875 sm_syslog(LOG_WARNING, e->e_id,
3876 "milter_data(%s): lied about quarantining, honoring request anyway",
3879 if (response == NULL)
3880 response = newstr("");
3881 if (MilterLogLevel > 3)
3882 sm_syslog(LOG_INFO, e->e_id,
3883 "milter=%s, quarantine=%s",
3884 m->mf_name, response);
3885 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool,
3887 macdefine(&e->e_macro, A_PERM,
3888 macid("{quarantine}"), e->e_quarmsg);
3891 case SMFIR_ADDHEADER:
3892 if (!bitset(SMFIF_ADDHDRS, m->mf_fflags))
3894 if (MilterLogLevel > 9)
3895 sm_syslog(LOG_WARNING, e->e_id,
3896 "milter_data(%s): lied about adding headers, honoring request anyway",
3899 milter_addheader(response, rlen, e);
3902 case SMFIR_INSHEADER:
3903 if (!bitset(SMFIF_ADDHDRS, m->mf_fflags))
3905 if (MilterLogLevel > 9)
3906 sm_syslog(LOG_WARNING, e->e_id,
3907 "milter_data(%s): lied about adding headers, honoring request anyway",
3910 milter_insheader(response, rlen, e);
3913 case SMFIR_CHGHEADER:
3914 if (!bitset(SMFIF_CHGHDRS, m->mf_fflags))
3916 if (MilterLogLevel > 9)
3917 sm_syslog(LOG_WARNING, e->e_id,
3918 "milter_data(%s): lied about changing headers, honoring request anyway",
3921 milter_changeheader(response, rlen, e);
3925 if (!bitset(SMFIF_ADDRCPT, m->mf_fflags))
3927 if (MilterLogLevel > 9)
3928 sm_syslog(LOG_WARNING, e->e_id,
3929 "milter_data(%s) lied about adding recipients, honoring request anyway",
3932 milter_addrcpt(response, rlen, e);
3936 if (!bitset(SMFIF_DELRCPT, m->mf_fflags))
3938 if (MilterLogLevel > 9)
3939 sm_syslog(LOG_WARNING, e->e_id,
3940 "milter_data(%s): lied about removing recipients, honoring request anyway",
3943 milter_delrcpt(response, rlen, e);
3946 case SMFIR_REPLBODY:
3947 if (!bitset(SMFIF_MODBODY, m->mf_fflags))
3949 if (MilterLogLevel > 0)
3950 sm_syslog(LOG_ERR, e->e_id,
3951 "milter_data(%s): lied about replacing body, rejecting request and tempfailing message",
3957 /* already failed in attempt */
3963 if (milter_reopen_df(e) < 0)
3972 if (milter_replbody(response, rlen,
3980 /* Invalid response to command */
3981 if (MilterLogLevel > 0)
3982 sm_syslog(LOG_ERR, e->e_id,
3983 "milter_data(%s): returned bogus response %c",
3988 if (rcmd != SMFIR_REPLYCODE && response != NULL)
3990 sm_free(response); /* XXX */
3994 if (m->mf_state == SMFS_ERROR)
3998 if (replbody && !replfailed)
4000 /* flush possible buffered character */
4001 milter_replbody(NULL, 0, !replbody, e);
4005 if (m->mf_state == SMFS_ERROR)
4007 MILTER_CHECK_ERROR(false, continue);
4013 /* leave things in the expected state if we touched it */
4016 if (*state == SMFIR_CONTINUE ||
4017 *state == SMFIR_ACCEPT)
4019 *state = SMFIR_TEMPFAIL;
4020 SM_FREE_CLR(response);
4025 (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT);
4027 e->e_flags &= ~EF_HAS_DF;
4033 if ((dfopen && milter_reset_df(e) < 0) ||
4034 (rewind && bfrewind(e->e_dfp) < 0))
4037 ExitStat = EX_IOERR;
4040 ** If filter told us to keep message but we had
4041 ** an error, we can't really keep it, tempfail it.
4044 if (*state == SMFIR_CONTINUE ||
4045 *state == SMFIR_ACCEPT)
4047 *state = SMFIR_TEMPFAIL;
4048 SM_FREE_CLR(response);
4052 syserr("milter_data: %s/%cf%s: read error",
4053 qid_printqueue(e->e_qgrp, e->e_qdir),
4054 DATAFL_LETTER, e->e_id);
4057 MILTER_CHECK_DONE_MSG();
4058 if (MilterLogLevel > 10 && *state == SMFIR_REJECT)
4059 sm_syslog(LOG_INFO, e->e_id, "Milter: reject, data");
4063 #if SMFI_VERSION > 2
4065 ** MILTER_UNKNOWN -- send any unrecognized or unimplemented command
4066 ** string to milter filters
4069 ** cmd -- the string itself.
4070 ** e -- current envelope.
4071 ** state -- return state from response.
4075 ** response string (may be NULL)
4079 milter_unknown(cmd, e, state)
4085 sm_dprintf("milter_unknown(%s)\n", cmd);
4087 return milter_command(SMFIC_UNKNOWN, cmd, strlen(cmd) + 1,
4090 #endif /* SMFI_VERSION > 2 */
4093 ** MILTER_QUIT -- informs the filter(s) we are done and closes connection(s)
4096 ** e -- current envelope.
4109 sm_dprintf("milter_quit(%s)\n", e->e_id);
4111 for (i = 0; InputFilters[i] != NULL; i++)
4112 milter_quit_filter(InputFilters[i], e);
4115 ** MILTER_ABORT -- informs the filter(s) that we are aborting current message
4118 ** e -- current envelope.
4131 sm_dprintf("milter_abort\n");
4133 for (i = 0; InputFilters[i] != NULL; i++)
4135 struct milter *m = InputFilters[i];
4138 if (m->mf_sock < 0 || m->mf_state != SMFS_INMSG)
4141 milter_abort_filter(m, e);