Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / sendmail / src / milter.c
1 /*
2  * Copyright (c) 1999-2003 Sendmail, Inc. and its suppliers.
3  *      All rights reserved.
4  *
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.
8  *
9  */
10
11 #include <sendmail.h>
12
13 SM_RCSID("@(#)$Id: milter.c,v 8.197.2.7 2003/03/22 18:54:25 ca Exp $")
14
15 #if MILTER
16 # include <libmilter/mfapi.h>
17 # include <libmilter/mfdef.h>
18
19 # include <errno.h>
20 # include <sys/time.h>
21
22 # if NETINET || NETINET6
23 #  include <arpa/inet.h>
24 # endif /* NETINET || NETINET6 */
25
26 # include <sm/fdset.h>
27
28 static void     milter_connect_timeout __P((void));
29 static void     milter_error __P((struct milter *, ENVELOPE *));
30 static int      milter_open __P((struct milter *, bool, ENVELOPE *));
31 static void     milter_parse_timeouts __P((char *, struct milter *));
32
33 static char *MilterConnectMacros[MAXFILTERMACROS + 1];
34 static char *MilterHeloMacros[MAXFILTERMACROS + 1];
35 static char *MilterEnvFromMacros[MAXFILTERMACROS + 1];
36 static char *MilterEnvRcptMacros[MAXFILTERMACROS + 1];
37
38 # define MILTER_CHECK_DONE_MSG() \
39         if (*state == SMFIR_REPLYCODE || \
40             *state == SMFIR_REJECT || \
41             *state == SMFIR_DISCARD || \
42             *state == SMFIR_TEMPFAIL) \
43         { \
44                 /* Abort the filters to let them know we are done with msg */ \
45                 milter_abort(e); \
46         }
47
48 # if _FFR_QUARANTINE
49 #  define MILTER_CHECK_ERROR(initial, action) \
50         if (!initial && tTd(71, 100)) \
51         { \
52                 if (e->e_quarmsg == NULL) \
53                 { \
54                         e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, \
55                                                          "filter failure"); \
56                         macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), \
57                                   e->e_quarmsg); \
58                 } \
59         } \
60         else if (tTd(71, 101)) \
61         { \
62                 if (e->e_quarmsg == NULL) \
63                 { \
64                         e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, \
65                                                          "filter failure"); \
66                         macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), \
67                                   e->e_quarmsg); \
68                 } \
69         } \
70         else if (bitnset(SMF_TEMPFAIL, m->mf_flags)) \
71                 *state = SMFIR_TEMPFAIL; \
72         else if (bitnset(SMF_REJECT, m->mf_flags)) \
73                 *state = SMFIR_REJECT; \
74         else \
75                 action;
76 # else /* _FFR_QUARANTINE */
77 #  define MILTER_CHECK_ERROR(initial, action) \
78         if (bitnset(SMF_TEMPFAIL, m->mf_flags)) \
79                 *state = SMFIR_TEMPFAIL; \
80         else if (bitnset(SMF_REJECT, m->mf_flags)) \
81                 *state = SMFIR_REJECT; \
82         else \
83                 action;
84 # endif /* _FFR_QUARANTINE */
85
86 # define MILTER_CHECK_REPLYCODE(default) \
87         if (response == NULL || \
88             strlen(response) + 1 != (size_t) rlen || \
89             rlen < 3 || \
90             (response[0] != '4' && response[0] != '5') || \
91             !isascii(response[1]) || !isdigit(response[1]) || \
92             !isascii(response[2]) || !isdigit(response[2])) \
93         { \
94                 if (response != NULL) \
95                         sm_free(response); /* XXX */ \
96                 response = newstr(default); \
97         } \
98         else \
99         { \
100                 char *ptr = response; \
101  \
102                 /* Check for unprotected %'s in the string */ \
103                 while (*ptr != '\0') \
104                 { \
105                         if (*ptr == '%' && *++ptr != '%') \
106                         { \
107                                 sm_free(response); /* XXX */ \
108                                 response = newstr(default); \
109                                 break; \
110                         } \
111                         ptr++; \
112                 } \
113         }
114
115 # define MILTER_DF_ERROR(msg) \
116 { \
117         int save_errno = errno; \
118  \
119         if (tTd(64, 5)) \
120         { \
121                 sm_dprintf(msg, dfname, sm_errstring(save_errno)); \
122                 sm_dprintf("\n"); \
123         } \
124         if (MilterLogLevel > 0) \
125                 sm_syslog(LOG_ERR, e->e_id, msg, dfname, sm_errstring(save_errno)); \
126         if (SuperSafe == SAFE_REALLY) \
127         { \
128                 if (e->e_dfp != NULL) \
129                 { \
130                         (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT); \
131                         e->e_dfp = NULL; \
132                 } \
133                 e->e_flags &= ~EF_HAS_DF; \
134         } \
135         errno = save_errno; \
136 }
137
138 /*
139 **  MILTER_TIMEOUT -- make sure socket is ready in time
140 **
141 **      Parameters:
142 **              routine -- routine name for debug/logging
143 **              secs -- number of seconds in timeout
144 **              write -- waiting to read or write?
145 **              started -- whether this is part of a previous sequence
146 **
147 **      Assumes 'm' is a milter structure for the current socket.
148 */
149
150 # define MILTER_TIMEOUT(routine, secs, write, started) \
151 { \
152         int ret; \
153         int save_errno; \
154         fd_set fds; \
155         struct timeval tv; \
156  \
157         if (SM_FD_SETSIZE > 0 && m->mf_sock >= SM_FD_SETSIZE) \
158         { \
159                 if (tTd(64, 5)) \
160                         sm_dprintf("milter_%s(%s): socket %d is larger than FD_SETSIZE %d\n", \
161                                    (routine), m->mf_name, m->mf_sock, \
162                                    SM_FD_SETSIZE); \
163                 if (MilterLogLevel > 0) \
164                         sm_syslog(LOG_ERR, e->e_id, \
165                                   "Milter (%s): socket(%s) %d is larger than FD_SETSIZE %d", \
166                                   m->mf_name, (routine), m->mf_sock, \
167                                   SM_FD_SETSIZE); \
168                 milter_error(m, e); \
169                 return NULL; \
170         } \
171  \
172         do \
173         { \
174                 FD_ZERO(&fds); \
175                 SM_FD_SET(m->mf_sock, &fds); \
176                 tv.tv_sec = (secs); \
177                 tv.tv_usec = 0; \
178                 ret = select(m->mf_sock + 1, \
179                              (write) ? NULL : &fds, \
180                              (write) ? &fds : NULL, \
181                              NULL, &tv); \
182         } while (ret < 0 && errno == EINTR); \
183  \
184         switch (ret) \
185         { \
186           case 0: \
187                 if (tTd(64, 5)) \
188                         sm_dprintf("milter_%s(%s): timeout\n", (routine), \
189                                    m->mf_name); \
190                 if (MilterLogLevel > 0) \
191                         sm_syslog(LOG_ERR, e->e_id, \
192                                   "Milter (%s): %s %s %s %s", \
193                                   m->mf_name, "timeout", \
194                                   started ? "during" : "before", \
195                                   "data", (routine)); \
196                 milter_error(m, e); \
197                 return NULL; \
198  \
199           case -1: \
200                 save_errno = errno; \
201                 if (tTd(64, 5)) \
202                         sm_dprintf("milter_%s(%s): select: %s\n", (routine), \
203                                    m->mf_name, sm_errstring(save_errno)); \
204                 if (MilterLogLevel > 0) \
205                 { \
206                         sm_syslog(LOG_ERR, e->e_id, \
207                                   "Milter (%s): select(%s): %s", \
208                                   m->mf_name, (routine), \
209                                   sm_errstring(save_errno)); \
210                 } \
211                 milter_error(m, e); \
212                 return NULL; \
213  \
214           default: \
215                 if (SM_FD_ISSET(m->mf_sock, &fds)) \
216                         break; \
217                 if (tTd(64, 5)) \
218                         sm_dprintf("milter_%s(%s): socket not ready\n", \
219                                 (routine), m->mf_name); \
220                 if (MilterLogLevel > 0) \
221                 { \
222                         sm_syslog(LOG_ERR, e->e_id, \
223                                   "Milter (%s): socket(%s) not ready", \
224                                   m->mf_name, (routine)); \
225                 } \
226                 milter_error(m, e); \
227                 return NULL; \
228         } \
229 }
230
231 /*
232 **  Low level functions
233 */
234
235 /*
236 **  MILTER_READ -- read from a remote milter filter
237 **
238 **      Parameters:
239 **              m -- milter to read from.
240 **              cmd -- return param for command read.
241 **              rlen -- return length of response string.
242 **              to -- timeout in seconds.
243 **              e -- current envelope.
244 **
245 **      Returns:
246 **              response string (may be NULL)
247 */
248
249 static char *
250 milter_sysread(m, buf, sz, to, e)
251         struct milter *m;
252         char *buf;
253         ssize_t sz;
254         time_t to;
255         ENVELOPE *e;
256 {
257         time_t readstart = 0;
258         ssize_t len, curl;
259         bool started = false;
260
261         curl = 0;
262
263         if (to > 0)
264                 readstart = curtime();
265
266         for (;;)
267         {
268                 if (to > 0)
269                 {
270                         time_t now;
271
272                         now = curtime();
273                         if (now - readstart >= to)
274                         {
275                                 if (tTd(64, 5))
276                                         sm_dprintf("milter_read (%s): %s %s %s",
277                                                   m->mf_name, "timeout",
278                                                   started ? "during" : "before",
279                                                   "data read");
280                                 if (MilterLogLevel > 0)
281                                         sm_syslog(LOG_ERR, e->e_id,
282                                                   "Milter (%s): %s %s %s",
283                                                   m->mf_name, "timeout",
284                                                   started ? "during" : "before",
285                                                   "data read");
286                                 milter_error(m, e);
287                                 return NULL;
288                         }
289                         to -= now - readstart;
290                         readstart = now;
291                         MILTER_TIMEOUT("read", to, false, started);
292                 }
293
294                 len = read(m->mf_sock, buf + curl, sz - curl);
295
296                 if (len < 0)
297                 {
298                         int save_errno = errno;
299
300                         if (tTd(64, 5))
301                                 sm_dprintf("milter_read(%s): read returned %ld: %s\n",
302                                         m->mf_name, (long) len,
303                                         sm_errstring(save_errno));
304                         if (MilterLogLevel > 0)
305                                 sm_syslog(LOG_ERR, e->e_id,
306                                           "Milter (%s): read returned %ld: %s",
307                                           m->mf_name, (long) len,
308                                           sm_errstring(save_errno));
309                         milter_error(m, e);
310                         return NULL;
311                 }
312
313                 started = true;
314                 curl += len;
315                 if (len == 0 || curl >= sz)
316                         break;
317
318         }
319
320         if (curl != sz)
321         {
322                 if (tTd(64, 5))
323                         sm_dprintf("milter_read(%s): cmd read returned %ld, expecting %ld\n",
324                                 m->mf_name, (long) curl, (long) sz);
325                 if (MilterLogLevel > 0)
326                         sm_syslog(LOG_ERR, e->e_id,
327                                   "milter_read(%s): cmd read returned %ld, expecting %ld",
328                                   m->mf_name, (long) curl, (long) sz);
329                 milter_error(m, e);
330                 return NULL;
331         }
332         return buf;
333 }
334
335 static char *
336 milter_read(m, cmd, rlen, to, e)
337         struct milter *m;
338         char *cmd;
339         ssize_t *rlen;
340         time_t to;
341         ENVELOPE *e;
342 {
343         time_t readstart = 0;
344         ssize_t expl;
345         mi_int32 i;
346         char *buf;
347         char data[MILTER_LEN_BYTES + 1];
348
349         *rlen = 0;
350         *cmd = '\0';
351
352         if (to > 0)
353                 readstart = curtime();
354
355         if (milter_sysread(m, data, sizeof data, to, e) == NULL)
356                 return NULL;
357
358         /* reset timeout */
359         if (to > 0)
360         {
361                 time_t now;
362
363                 now = curtime();
364                 if (now - readstart >= to)
365                 {
366                         if (tTd(64, 5))
367                                 sm_dprintf("milter_read(%s): timeout before data read\n",
368                                         m->mf_name);
369                         if (MilterLogLevel > 0)
370                                 sm_syslog(LOG_ERR, e->e_id,
371                                           "Milter read(%s): timeout before data read",
372                                           m->mf_name);
373                         milter_error(m, e);
374                         return NULL;
375                 }
376                 to -= now - readstart;
377         }
378
379         *cmd = data[MILTER_LEN_BYTES];
380         data[MILTER_LEN_BYTES] = '\0';
381         (void) memcpy(&i, data, MILTER_LEN_BYTES);
382         expl = ntohl(i) - 1;
383
384         if (tTd(64, 25))
385                 sm_dprintf("milter_read(%s): expecting %ld bytes\n",
386                         m->mf_name, (long) expl);
387
388         if (expl < 0)
389         {
390                 if (tTd(64, 5))
391                         sm_dprintf("milter_read(%s): read size %ld out of range\n",
392                                 m->mf_name, (long) expl);
393                 if (MilterLogLevel > 0)
394                         sm_syslog(LOG_ERR, e->e_id,
395                                   "milter_read(%s): read size %ld out of range",
396                                   m->mf_name, (long) expl);
397                 milter_error(m, e);
398                 return NULL;
399         }
400
401         if (expl == 0)
402                 return NULL;
403
404         buf = (char *) xalloc(expl);
405
406         if (milter_sysread(m, buf, expl, to, e) == NULL)
407         {
408                 sm_free(buf); /* XXX */
409                 return NULL;
410         }
411
412         if (tTd(64, 50))
413                 sm_dprintf("milter_read(%s): Returning %*s\n",
414                         m->mf_name, (int) expl, buf);
415         *rlen = expl;
416         return buf;
417 }
418 /*
419 **  MILTER_WRITE -- write to a remote milter filter
420 **
421 **      Parameters:
422 **              m -- milter to read from.
423 **              cmd -- command to send.
424 **              buf -- optional command data.
425 **              len -- length of buf.
426 **              to -- timeout in seconds.
427 **              e -- current envelope.
428 **
429 **      Returns:
430 **              buf if successful, NULL otherwise
431 **              Not actually used anywhere but function prototype
432 **                      must match milter_read()
433 */
434
435 static char *
436 milter_write(m, cmd, buf, len, to, e)
437         struct milter *m;
438         char cmd;
439         char *buf;
440         ssize_t len;
441         time_t to;
442         ENVELOPE *e;
443 {
444         time_t writestart = (time_t) 0;
445         ssize_t sl, i;
446         mi_int32 nl;
447         char data[MILTER_LEN_BYTES + 1];
448         bool started = false;
449
450         if (len < 0 || len > MILTER_CHUNK_SIZE)
451         {
452                 if (tTd(64, 5))
453                         sm_dprintf("milter_write(%s): length %ld out of range\n",
454                                 m->mf_name, (long) len);
455                 if (MilterLogLevel > 0)
456                         sm_syslog(LOG_ERR, e->e_id,
457                                   "milter_write(%s): length %ld out of range",
458                                   m->mf_name, (long) len);
459                 milter_error(m, e);
460                 return NULL;
461         }
462
463         if (tTd(64, 20))
464                 sm_dprintf("milter_write(%s): cmd %c, len %ld\n",
465                            m->mf_name, cmd, (long) len);
466
467         nl = htonl(len + 1);    /* add 1 for the cmd char */
468         (void) memcpy(data, (char *) &nl, MILTER_LEN_BYTES);
469         data[MILTER_LEN_BYTES] = cmd;
470         sl = MILTER_LEN_BYTES + 1;
471
472         if (to > 0)
473         {
474                 writestart = curtime();
475                 MILTER_TIMEOUT("write", to, true, started);
476         }
477
478         /* use writev() instead to send the whole stuff at once? */
479         i = write(m->mf_sock, (void *) data, sl);
480         if (i != sl)
481         {
482                 int save_errno = errno;
483
484                 if (tTd(64, 5))
485                         sm_dprintf("milter_write (%s): write(%c) returned %ld, expected %ld: %s\n",
486                                    m->mf_name, cmd, (long) i, (long) sl,
487                                    sm_errstring(save_errno));
488                 if (MilterLogLevel > 0)
489                         sm_syslog(LOG_ERR, e->e_id,
490                                   "Milter (%s): write(%c) returned %ld, expected %ld: %s",
491                                   m->mf_name, cmd, (long) i, (long) sl,
492                                   sm_errstring(save_errno));
493                 milter_error(m, e);
494                 return buf;
495         }
496
497         if (len <= 0 || buf == NULL)
498                 return buf;
499
500         if (tTd(64, 50))
501                 sm_dprintf("milter_write(%s): Sending %*s\n",
502                            m->mf_name, (int) len, buf);
503         started = true;
504
505         if (to > 0)
506         {
507                 time_t now;
508
509                 now = curtime();
510                 if (now - writestart >= to)
511                 {
512                         if (tTd(64, 5))
513                                 sm_dprintf("milter_write(%s): timeout before data write\n",
514                                            m->mf_name);
515                         if (MilterLogLevel > 0)
516                                 sm_syslog(LOG_ERR, e->e_id,
517                                           "Milter (%s): timeout before data write",
518                                           m->mf_name);
519                         milter_error(m, e);
520                         return NULL;
521                 }
522                 else
523                 {
524                         to -= now - writestart;
525                         MILTER_TIMEOUT("write", to, true, started);
526                 }
527         }
528
529         i = write(m->mf_sock, (void *) buf, len);
530         if (i != len)
531         {
532                 int save_errno = errno;
533
534                 if (tTd(64, 5))
535                         sm_dprintf("milter_write(%s): write(%c) returned %ld, expected %ld: %s\n",
536                                    m->mf_name, cmd, (long) i, (long) sl,
537                                    sm_errstring(save_errno));
538                 if (MilterLogLevel > 0)
539                         sm_syslog(LOG_ERR, e->e_id,
540                                   "Milter (%s): write(%c) returned %ld, expected %ld: %s",
541                                   m->mf_name, cmd, (long) i, (long) len,
542                                   sm_errstring(save_errno));
543                 milter_error(m, e);
544                 return NULL;
545         }
546         return buf;
547 }
548
549 /*
550 **  Utility functions
551 */
552
553 /*
554 **  MILTER_OPEN -- connect to remote milter filter
555 **
556 **      Parameters:
557 **              m -- milter to connect to.
558 **              parseonly -- parse but don't connect.
559 **              e -- current envelope.
560 **
561 **      Returns:
562 **              connected socket if successful && !parseonly,
563 **              0 upon parse success if parseonly,
564 **              -1 otherwise.
565 */
566
567 static jmp_buf  MilterConnectTimeout;
568
569 static int
570 milter_open(m, parseonly, e)
571         struct milter *m;
572         bool parseonly;
573         ENVELOPE *e;
574 {
575         int sock = 0;
576         SOCKADDR_LEN_T addrlen = 0;
577         int addrno = 0;
578         int save_errno;
579         char *p;
580         char *colon;
581         char *at;
582         struct hostent *hp = NULL;
583         SOCKADDR addr;
584
585         if (m->mf_conn == NULL || m->mf_conn[0] == '\0')
586         {
587                 if (tTd(64, 5))
588                         sm_dprintf("X%s: empty or missing socket information\n",
589                                    m->mf_name);
590                 if (parseonly)
591                         syserr("X%s: empty or missing socket information",
592                                m->mf_name);
593                 else if (MilterLogLevel > 0)
594                         sm_syslog(LOG_ERR, e->e_id,
595                                   "Milter (%s): empty or missing socket information",
596                                   m->mf_name);
597                 milter_error(m, e);
598                 return -1;
599         }
600
601         /* protocol:filename or protocol:port@host */
602         memset(&addr, '\0', sizeof addr);
603         p = m->mf_conn;
604         colon = strchr(p, ':');
605         if (colon != NULL)
606         {
607                 *colon = '\0';
608
609                 if (*p == '\0')
610                 {
611 # if NETUNIX
612                         /* default to AF_UNIX */
613                         addr.sa.sa_family = AF_UNIX;
614 # else /* NETUNIX */
615 #  if NETINET
616                         /* default to AF_INET */
617                         addr.sa.sa_family = AF_INET;
618 #  else /* NETINET */
619 #   if NETINET6
620                         /* default to AF_INET6 */
621                         addr.sa.sa_family = AF_INET6;
622 #   else /* NETINET6 */
623                         /* no protocols available */
624                         if (MilterLogLevel > 0)
625                                 sm_syslog(LOG_ERR, e->e_id,
626                                           "Milter (%s): no valid socket protocols available",
627                                           m->mf_name);
628                         milter_error(m, e);
629                         return -1;
630 #   endif /* NETINET6 */
631 #  endif /* NETINET */
632 # endif /* NETUNIX */
633                 }
634 # if NETUNIX
635                 else if (sm_strcasecmp(p, "unix") == 0 ||
636                          sm_strcasecmp(p, "local") == 0)
637                         addr.sa.sa_family = AF_UNIX;
638 # endif /* NETUNIX */
639 # if NETINET
640                 else if (sm_strcasecmp(p, "inet") == 0)
641                         addr.sa.sa_family = AF_INET;
642 # endif /* NETINET */
643 # if NETINET6
644                 else if (sm_strcasecmp(p, "inet6") == 0)
645                         addr.sa.sa_family = AF_INET6;
646 # endif /* NETINET6 */
647                 else
648                 {
649 # ifdef EPROTONOSUPPORT
650                         errno = EPROTONOSUPPORT;
651 # else /* EPROTONOSUPPORT */
652                         errno = EINVAL;
653 # endif /* EPROTONOSUPPORT */
654                         if (tTd(64, 5))
655                                 sm_dprintf("X%s: unknown socket type %s\n",
656                                         m->mf_name, p);
657                         if (parseonly)
658                                 syserr("X%s: unknown socket type %s",
659                                        m->mf_name, p);
660                         else if (MilterLogLevel > 0)
661                                 sm_syslog(LOG_ERR, e->e_id,
662                                           "Milter (%s): unknown socket type %s",
663                                           m->mf_name, p);
664                         milter_error(m, e);
665                         return -1;
666                 }
667                 *colon++ = ':';
668         }
669         else
670         {
671                 /* default to AF_UNIX */
672                 addr.sa.sa_family = AF_UNIX;
673                 colon = p;
674         }
675
676 # if NETUNIX
677         if (addr.sa.sa_family == AF_UNIX)
678         {
679                 long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_EXECOK;
680
681                 at = colon;
682                 if (strlen(colon) >= sizeof addr.sunix.sun_path)
683                 {
684                         if (tTd(64, 5))
685                                 sm_dprintf("X%s: local socket name %s too long\n",
686                                         m->mf_name, colon);
687                         errno = EINVAL;
688                         if (parseonly)
689                                 syserr("X%s: local socket name %s too long",
690                                        m->mf_name, colon);
691                         else if (MilterLogLevel > 0)
692                                 sm_syslog(LOG_ERR, e->e_id,
693                                           "Milter (%s): local socket name %s too long",
694                                           m->mf_name, colon);
695                         milter_error(m, e);
696                         return -1;
697                 }
698                 errno = safefile(colon, RunAsUid, RunAsGid, RunAsUserName, sff,
699                                  S_IRUSR|S_IWUSR, NULL);
700
701                 /* if just parsing .cf file, socket doesn't need to exist */
702                 if (parseonly && errno == ENOENT)
703                 {
704                         if (OpMode == MD_DAEMON ||
705                             OpMode == MD_FGDAEMON)
706                                 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
707                                                      "WARNING: X%s: local socket name %s missing\n",
708                                                      m->mf_name, colon);
709                 }
710                 else if (errno != 0)
711                 {
712                         /* if not safe, don't create */
713                         save_errno = errno;
714                         if (tTd(64, 5))
715                                 sm_dprintf("X%s: local socket name %s unsafe\n",
716                                         m->mf_name, colon);
717                         errno = save_errno;
718                         if (parseonly)
719                         {
720                                 if (OpMode == MD_DAEMON ||
721                                     OpMode == MD_FGDAEMON ||
722                                     OpMode == MD_SMTP)
723                                         syserr("X%s: local socket name %s unsafe",
724                                                m->mf_name, colon);
725                         }
726                         else if (MilterLogLevel > 0)
727                                 sm_syslog(LOG_ERR, e->e_id,
728                                           "Milter (%s): local socket name %s unsafe",
729                                           m->mf_name, colon);
730                         milter_error(m, e);
731                         return -1;
732                 }
733
734                 (void) sm_strlcpy(addr.sunix.sun_path, colon,
735                                sizeof addr.sunix.sun_path);
736                 addrlen = sizeof (struct sockaddr_un);
737         }
738         else
739 # endif /* NETUNIX */
740 # if NETINET || NETINET6
741         if (false
742 #  if NETINET
743                  || addr.sa.sa_family == AF_INET
744 #  endif /* NETINET */
745 #  if NETINET6
746                  || addr.sa.sa_family == AF_INET6
747 #  endif /* NETINET6 */
748                  )
749         {
750                 unsigned short port;
751
752                 /* Parse port@host */
753                 at = strchr(colon, '@');
754                 if (at == NULL)
755                 {
756                         if (tTd(64, 5))
757                                 sm_dprintf("X%s: bad address %s (expected port@host)\n",
758                                         m->mf_name, colon);
759                         if (parseonly)
760                                 syserr("X%s: bad address %s (expected port@host)",
761                                        m->mf_name, colon);
762                         else if (MilterLogLevel > 0)
763                                 sm_syslog(LOG_ERR, e->e_id,
764                                           "Milter (%s): bad address %s (expected port@host)",
765                                           m->mf_name, colon);
766                         milter_error(m, e);
767                         return -1;
768                 }
769                 *at = '\0';
770                 if (isascii(*colon) && isdigit(*colon))
771                         port = htons((unsigned short) atoi(colon));
772                 else
773                 {
774 #  ifdef NO_GETSERVBYNAME
775                         if (tTd(64, 5))
776                                 sm_dprintf("X%s: invalid port number %s\n",
777                                         m->mf_name, colon);
778                         if (parseonly)
779                                 syserr("X%s: invalid port number %s",
780                                        m->mf_name, colon);
781                         else if (MilterLogLevel > 0)
782                                 sm_syslog(LOG_ERR, e->e_id,
783                                           "Milter (%s): invalid port number %s",
784                                           m->mf_name, colon);
785                         milter_error(m, e);
786                         return -1;
787 #  else /* NO_GETSERVBYNAME */
788                         register struct servent *sp;
789
790                         sp = getservbyname(colon, "tcp");
791                         if (sp == NULL)
792                         {
793                                 save_errno = errno;
794                                 if (tTd(64, 5))
795                                         sm_dprintf("X%s: unknown port name %s\n",
796                                                 m->mf_name, colon);
797                                 errno = save_errno;
798                                 if (parseonly)
799                                         syserr("X%s: unknown port name %s",
800                                                m->mf_name, colon);
801                                 else if (MilterLogLevel > 0)
802                                         sm_syslog(LOG_ERR, e->e_id,
803                                                   "Milter (%s): unknown port name %s",
804                                                   m->mf_name, colon);
805                                 milter_error(m, e);
806                                 return -1;
807                         }
808                         port = sp->s_port;
809 #  endif /* NO_GETSERVBYNAME */
810                 }
811                 *at++ = '@';
812                 if (*at == '[')
813                 {
814                         char *end;
815
816                         end = strchr(at, ']');
817                         if (end != NULL)
818                         {
819                                 bool found = false;
820 #  if NETINET
821                                 unsigned long hid = INADDR_NONE;
822 #  endif /* NETINET */
823 #  if NETINET6
824                                 struct sockaddr_in6 hid6;
825 #  endif /* NETINET6 */
826
827                                 *end = '\0';
828 #  if NETINET
829                                 if (addr.sa.sa_family == AF_INET &&
830                                     (hid = inet_addr(&at[1])) != INADDR_NONE)
831                                 {
832                                         addr.sin.sin_addr.s_addr = hid;
833                                         addr.sin.sin_port = port;
834                                         found = true;
835                                 }
836 #  endif /* NETINET */
837 #  if NETINET6
838                                 (void) memset(&hid6, '\0', sizeof hid6);
839                                 if (addr.sa.sa_family == AF_INET6 &&
840                                     anynet_pton(AF_INET6, &at[1],
841                                                 &hid6.sin6_addr) == 1)
842                                 {
843                                         addr.sin6.sin6_addr = hid6.sin6_addr;
844                                         addr.sin6.sin6_port = port;
845                                         found = true;
846                                 }
847 #  endif /* NETINET6 */
848                                 *end = ']';
849                                 if (!found)
850                                 {
851                                         if (tTd(64, 5))
852                                                 sm_dprintf("X%s: Invalid numeric domain spec \"%s\"\n",
853                                                         m->mf_name, at);
854                                         if (parseonly)
855                                                 syserr("X%s: Invalid numeric domain spec \"%s\"",
856                                                        m->mf_name, at);
857                                         else if (MilterLogLevel > 0)
858                                                 sm_syslog(LOG_ERR, e->e_id,
859                                                           "Milter (%s): Invalid numeric domain spec \"%s\"",
860                                                           m->mf_name, at);
861                                         milter_error(m, e);
862                                         return -1;
863                                 }
864                         }
865                         else
866                         {
867                                 if (tTd(64, 5))
868                                         sm_dprintf("X%s: Invalid numeric domain spec \"%s\"\n",
869                                                 m->mf_name, at);
870                                 if (parseonly)
871                                         syserr("X%s: Invalid numeric domain spec \"%s\"",
872                                                m->mf_name, at);
873                                 else if (MilterLogLevel > 0)
874                                         sm_syslog(LOG_ERR, e->e_id,
875                                                   "Milter (%s): Invalid numeric domain spec \"%s\"",
876                                                   m->mf_name, at);
877                                 milter_error(m, e);
878                                 return -1;
879                         }
880                 }
881                 else
882                 {
883                         hp = sm_gethostbyname(at, addr.sa.sa_family);
884                         if (hp == NULL)
885                         {
886                                 save_errno = errno;
887                                 if (tTd(64, 5))
888                                         sm_dprintf("X%s: Unknown host name %s\n",
889                                                    m->mf_name, at);
890                                 errno = save_errno;
891                                 if (parseonly)
892                                         syserr("X%s: Unknown host name %s",
893                                                m->mf_name, at);
894                                 else if (MilterLogLevel > 0)
895                                         sm_syslog(LOG_ERR, e->e_id,
896                                                   "Milter (%s): Unknown host name %s",
897                                                   m->mf_name, at);
898                                 milter_error(m, e);
899                                 return -1;
900                         }
901                         addr.sa.sa_family = hp->h_addrtype;
902                         switch (hp->h_addrtype)
903                         {
904 #  if NETINET
905                           case AF_INET:
906                                 memmove(&addr.sin.sin_addr,
907                                         hp->h_addr, INADDRSZ);
908                                 addr.sin.sin_port = port;
909                                 addrlen = sizeof (struct sockaddr_in);
910                                 addrno = 1;
911                                 break;
912 #  endif /* NETINET */
913
914 #  if NETINET6
915                           case AF_INET6:
916                                 memmove(&addr.sin6.sin6_addr,
917                                         hp->h_addr, IN6ADDRSZ);
918                                 addr.sin6.sin6_port = port;
919                                 addrlen = sizeof (struct sockaddr_in6);
920                                 addrno = 1;
921                                 break;
922 #  endif /* NETINET6 */
923
924                           default:
925                                 if (tTd(64, 5))
926                                         sm_dprintf("X%s: Unknown protocol for %s (%d)\n",
927                                                    m->mf_name, at,
928                                                    hp->h_addrtype);
929                                 if (parseonly)
930                                         syserr("X%s: Unknown protocol for %s (%d)",
931                                                m->mf_name, at, hp->h_addrtype);
932                                 else if (MilterLogLevel > 0)
933                                         sm_syslog(LOG_ERR, e->e_id,
934                                                   "Milter (%s): Unknown protocol for %s (%d)",
935                                                   m->mf_name, at,
936                                                   hp->h_addrtype);
937                                 milter_error(m, e);
938 #  if NETINET6
939                                 freehostent(hp);
940 #  endif /* NETINET6 */
941                                 return -1;
942                         }
943                 }
944         }
945         else
946 # endif /* NETINET || NETINET6 */
947         {
948                 if (tTd(64, 5))
949                         sm_dprintf("X%s: unknown socket protocol\n",
950                                    m->mf_name);
951                 if (parseonly)
952                         syserr("X%s: unknown socket protocol", m->mf_name);
953                 else if (MilterLogLevel > 0)
954                         sm_syslog(LOG_ERR, e->e_id,
955                                   "Milter (%s): unknown socket protocol",
956                                   m->mf_name);
957                 milter_error(m, e);
958                 return -1;
959         }
960
961         /* just parsing through? */
962         if (parseonly)
963         {
964                 m->mf_state = SMFS_READY;
965 # if NETINET6
966                 if (hp != NULL)
967                         freehostent(hp);
968 # endif /* NETINET6 */
969                 return 0;
970         }
971
972         /* sanity check */
973         if (m->mf_state != SMFS_READY &&
974             m->mf_state != SMFS_CLOSED)
975         {
976                 /* shouldn't happen */
977                 if (tTd(64, 1))
978                         sm_dprintf("Milter (%s): Trying to open filter in state %c\n",
979                                    m->mf_name, (char) m->mf_state);
980                 milter_error(m, e);
981 # if NETINET6
982                 if (hp != NULL)
983                         freehostent(hp);
984 # endif /* NETINET6 */
985                 return -1;
986         }
987
988         /* nope, actually connecting */
989         for (;;)
990         {
991                 sock = socket(addr.sa.sa_family, SOCK_STREAM, 0);
992                 if (sock < 0)
993                 {
994                         save_errno = errno;
995                         if (tTd(64, 5))
996                                 sm_dprintf("Milter (%s): error creating socket: %s\n",
997                                            m->mf_name,
998                                            sm_errstring(save_errno));
999                         if (MilterLogLevel > 0)
1000                                 sm_syslog(LOG_ERR, e->e_id,
1001                                           "Milter (%s): error creating socket: %s",
1002                                           m->mf_name, sm_errstring(save_errno));
1003                         milter_error(m, e);
1004 # if NETINET6
1005                         if (hp != NULL)
1006                                 freehostent(hp);
1007 # endif /* NETINET6 */
1008                         return -1;
1009                 }
1010
1011                 if (setjmp(MilterConnectTimeout) == 0)
1012                 {
1013                         SM_EVENT *ev = NULL;
1014                         int i;
1015
1016                         if (m->mf_timeout[SMFTO_CONNECT] > 0)
1017                                 ev = sm_setevent(m->mf_timeout[SMFTO_CONNECT],
1018                                                  milter_connect_timeout, 0);
1019
1020                         i = connect(sock, (struct sockaddr *) &addr, addrlen);
1021                         save_errno = errno;
1022                         if (ev != NULL)
1023                                 sm_clrevent(ev);
1024                         errno = save_errno;
1025                         if (i >= 0)
1026                                 break;
1027                 }
1028
1029                 /* couldn't connect.... try next address */
1030                 save_errno = errno;
1031                 p = CurHostName;
1032                 CurHostName = at;
1033                 if (tTd(64, 5))
1034                         sm_dprintf("milter_open (%s): open %s failed: %s\n",
1035                                    m->mf_name, at, sm_errstring(save_errno));
1036                 if (MilterLogLevel > 13)
1037                         sm_syslog(LOG_INFO, e->e_id,
1038                                   "Milter (%s): open %s failed: %s",
1039                                   m->mf_name, at, sm_errstring(save_errno));
1040                 CurHostName = p;
1041                 (void) close(sock);
1042
1043                 /* try next address */
1044                 if (hp != NULL && hp->h_addr_list[addrno] != NULL)
1045                 {
1046                         switch (addr.sa.sa_family)
1047                         {
1048 # if NETINET
1049                           case AF_INET:
1050                                 memmove(&addr.sin.sin_addr,
1051                                         hp->h_addr_list[addrno++],
1052                                         INADDRSZ);
1053                                 break;
1054 # endif /* NETINET */
1055
1056 # if NETINET6
1057                           case AF_INET6:
1058                                 memmove(&addr.sin6.sin6_addr,
1059                                         hp->h_addr_list[addrno++],
1060                                         IN6ADDRSZ);
1061                                 break;
1062 # endif /* NETINET6 */
1063
1064                           default:
1065                                 if (tTd(64, 5))
1066                                         sm_dprintf("X%s: Unknown protocol for %s (%d)\n",
1067                                                    m->mf_name, at,
1068                                                    hp->h_addrtype);
1069                                 if (MilterLogLevel > 0)
1070                                         sm_syslog(LOG_ERR, e->e_id,
1071                                                   "Milter (%s): Unknown protocol for %s (%d)",
1072                                                   m->mf_name, at,
1073                                                   hp->h_addrtype);
1074                                 milter_error(m, e);
1075 # if NETINET6
1076                                 freehostent(hp);
1077 # endif /* NETINET6 */
1078                                 return -1;
1079                         }
1080                         continue;
1081                 }
1082                 p = CurHostName;
1083                 CurHostName = at;
1084                 if (tTd(64, 5))
1085                         sm_dprintf("X%s: error connecting to filter: %s\n",
1086                                    m->mf_name, sm_errstring(save_errno));
1087                 if (MilterLogLevel > 0)
1088                         sm_syslog(LOG_ERR, e->e_id,
1089                                   "Milter (%s): error connecting to filter: %s",
1090                                   m->mf_name, sm_errstring(save_errno));
1091                 CurHostName = p;
1092                 milter_error(m, e);
1093 # if NETINET6
1094                 if (hp != NULL)
1095                         freehostent(hp);
1096 # endif /* NETINET6 */
1097                 return -1;
1098         }
1099         m->mf_state = SMFS_OPEN;
1100 # if NETINET6
1101         if (hp != NULL)
1102         {
1103                 freehostent(hp);
1104                 hp = NULL;
1105         }
1106 # endif /* NETINET6 */
1107         return sock;
1108 }
1109
1110 static void
1111 milter_connect_timeout()
1112 {
1113         /*
1114         **  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
1115         **      ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
1116         **      DOING.
1117         */
1118
1119         errno = ETIMEDOUT;
1120         longjmp(MilterConnectTimeout, 1);
1121 }
1122 /*
1123 **  MILTER_SETUP -- setup structure for a mail filter
1124 **
1125 **      Parameters:
1126 **              line -- the options line.
1127 **
1128 **      Returns:
1129 **              none
1130 */
1131
1132 void
1133 milter_setup(line)
1134         char *line;
1135 {
1136         char fcode;
1137         register char *p;
1138         register struct milter *m;
1139         STAB *s;
1140
1141         /* collect the filter name */
1142         for (p = line;
1143              *p != '\0' && *p != ',' && !(isascii(*p) && isspace(*p));
1144              p++)
1145                 continue;
1146         if (*p != '\0')
1147                 *p++ = '\0';
1148         if (line[0] == '\0')
1149         {
1150                 syserr("name required for mail filter");
1151                 return;
1152         }
1153         m = (struct milter *) xalloc(sizeof *m);
1154         memset((char *) m, '\0', sizeof *m);
1155         m->mf_name = newstr(line);
1156         m->mf_state = SMFS_READY;
1157         m->mf_sock = -1;
1158         m->mf_timeout[SMFTO_CONNECT] = (time_t) 300;
1159         m->mf_timeout[SMFTO_WRITE] = (time_t) 10;
1160         m->mf_timeout[SMFTO_READ] = (time_t) 10;
1161         m->mf_timeout[SMFTO_EOM] = (time_t) 300;
1162
1163         /* now scan through and assign info from the fields */
1164         while (*p != '\0')
1165         {
1166                 char *delimptr;
1167
1168                 while (*p != '\0' &&
1169                        (*p == ',' || (isascii(*p) && isspace(*p))))
1170                         p++;
1171
1172                 /* p now points to field code */
1173                 fcode = *p;
1174                 while (*p != '\0' && *p != '=' && *p != ',')
1175                         p++;
1176                 if (*p++ != '=')
1177                 {
1178                         syserr("X%s: `=' expected", m->mf_name);
1179                         return;
1180                 }
1181                 while (isascii(*p) && isspace(*p))
1182                         p++;
1183
1184                 /* p now points to the field body */
1185                 p = munchstring(p, &delimptr, ',');
1186
1187                 /* install the field into the filter struct */
1188                 switch (fcode)
1189                 {
1190                   case 'S':             /* socket */
1191                         if (p == NULL)
1192                                 m->mf_conn = NULL;
1193                         else
1194                                 m->mf_conn = newstr(p);
1195                         break;
1196
1197                   case 'F':             /* Milter flags configured on MTA */
1198                         for (; *p != '\0'; p++)
1199                         {
1200                                 if (!(isascii(*p) && isspace(*p)))
1201                                         setbitn(bitidx(*p), m->mf_flags);
1202                         }
1203                         break;
1204
1205                   case 'T':             /* timeouts */
1206                         milter_parse_timeouts(p, m);
1207                         break;
1208
1209                   default:
1210                         syserr("X%s: unknown filter equate %c=",
1211                                m->mf_name, fcode);
1212                         break;
1213                 }
1214                 p = delimptr;
1215         }
1216
1217         /* early check for errors */
1218         (void) milter_open(m, true, CurEnv);
1219
1220         /* enter the filter into the symbol table */
1221         s = stab(m->mf_name, ST_MILTER, ST_ENTER);
1222         if (s->s_milter != NULL)
1223                 syserr("X%s: duplicate filter definition", m->mf_name);
1224         else
1225                 s->s_milter = m;
1226 }
1227 /*
1228 **  MILTER_CONFIG -- parse option list into an array and check config
1229 **
1230 **      Called when reading configuration file.
1231 **
1232 **      Parameters:
1233 **              spec -- the filter list.
1234 **              list -- the array to fill in.
1235 **              max -- the maximum number of entries in list.
1236 **
1237 **      Returns:
1238 **              none
1239 */
1240
1241 void
1242 milter_config(spec, list, max)
1243         char *spec;
1244         struct milter **list;
1245         int max;
1246 {
1247         int numitems = 0;
1248         register char *p;
1249
1250         /* leave one for the NULL signifying the end of the list */
1251         max--;
1252
1253         for (p = spec; p != NULL; )
1254         {
1255                 STAB *s;
1256
1257                 while (isascii(*p) && isspace(*p))
1258                         p++;
1259                 if (*p == '\0')
1260                         break;
1261                 spec = p;
1262
1263                 if (numitems >= max)
1264                 {
1265                         syserr("Too many filters defined, %d max", max);
1266                         if (max > 0)
1267                                 list[0] = NULL;
1268                         return;
1269                 }
1270 #if _FFR_MILTER_PERDAEMON
1271                 p = strpbrk(p, ";,");
1272 #else /* _FFR_MILTER_PERDAEMON */
1273                 p = strpbrk(p, ",");
1274 #endif /* _FFR_MILTER_PERDAEMON */
1275                 if (p != NULL)
1276                         *p++ = '\0';
1277
1278                 s = stab(spec, ST_MILTER, ST_FIND);
1279                 if (s == NULL)
1280                 {
1281                         syserr("InputFilter %s not defined", spec);
1282                         ExitStat = EX_CONFIG;
1283                         return;
1284                 }
1285                 list[numitems++] = s->s_milter;
1286         }
1287         list[numitems] = NULL;
1288
1289         /* if not set, set to LogLevel */
1290         if (MilterLogLevel == -1)
1291                 MilterLogLevel = LogLevel;
1292 }
1293 /*
1294 **  MILTER_PARSE_TIMEOUTS -- parse timeout list
1295 **
1296 **      Called when reading configuration file.
1297 **
1298 **      Parameters:
1299 **              spec -- the timeout list.
1300 **              m -- milter to set.
1301 **
1302 **      Returns:
1303 **              none
1304 */
1305
1306 static void
1307 milter_parse_timeouts(spec, m)
1308         char *spec;
1309         struct milter *m;
1310 {
1311         char fcode;
1312         register char *p;
1313
1314         p = spec;
1315
1316         /* now scan through and assign info from the fields */
1317         while (*p != '\0')
1318         {
1319                 char *delimptr;
1320
1321                 while (*p != '\0' &&
1322                        (*p == ';' || (isascii(*p) && isspace(*p))))
1323                         p++;
1324
1325                 /* p now points to field code */
1326                 fcode = *p;
1327                 while (*p != '\0' && *p != ':')
1328                         p++;
1329                 if (*p++ != ':')
1330                 {
1331                         syserr("X%s, T=: `:' expected", m->mf_name);
1332                         return;
1333                 }
1334                 while (isascii(*p) && isspace(*p))
1335                         p++;
1336
1337                 /* p now points to the field body */
1338                 p = munchstring(p, &delimptr, ';');
1339
1340                 /* install the field into the filter struct */
1341                 switch (fcode)
1342                 {
1343                   case 'C':
1344                         m->mf_timeout[SMFTO_CONNECT] = convtime(p, 's');
1345                         if (tTd(64, 5))
1346                                 sm_dprintf("X%s: %c=%lu\n",
1347                                            m->mf_name, fcode,
1348                                            (unsigned long) m->mf_timeout[SMFTO_CONNECT]);
1349                         break;
1350
1351                   case 'S':
1352                         m->mf_timeout[SMFTO_WRITE] = convtime(p, 's');
1353                         if (tTd(64, 5))
1354                                 sm_dprintf("X%s: %c=%lu\n",
1355                                            m->mf_name, fcode,
1356                                            (unsigned long) m->mf_timeout[SMFTO_WRITE]);
1357                         break;
1358
1359                   case 'R':
1360                         m->mf_timeout[SMFTO_READ] = convtime(p, 's');
1361                         if (tTd(64, 5))
1362                                 sm_dprintf("X%s: %c=%lu\n",
1363                                            m->mf_name, fcode,
1364                                            (unsigned long) m->mf_timeout[SMFTO_READ]);
1365                         break;
1366
1367                   case 'E':
1368                         m->mf_timeout[SMFTO_EOM] = convtime(p, 's');
1369                         if (tTd(64, 5))
1370                                 sm_dprintf("X%s: %c=%lu\n",
1371                                            m->mf_name, fcode,
1372                                            (unsigned long) m->mf_timeout[SMFTO_EOM]);
1373                         break;
1374
1375                   default:
1376                         if (tTd(64, 5))
1377                                 sm_dprintf("X%s: %c unknown\n",
1378                                            m->mf_name, fcode);
1379                         syserr("X%s: unknown filter timeout %c",
1380                                m->mf_name, fcode);
1381                         break;
1382                 }
1383                 p = delimptr;
1384         }
1385 }
1386 /*
1387 **  MILTER_SET_OPTION -- set an individual milter option
1388 **
1389 **      Parameters:
1390 **              name -- the name of the option.
1391 **              val -- the value of the option.
1392 **              sticky -- if set, don't let other setoptions override
1393 **                      this value.
1394 **
1395 **      Returns:
1396 **              none.
1397 */
1398
1399 /* set if Milter sub-option is stuck */
1400 static BITMAP256        StickyMilterOpt;
1401
1402 static struct milteropt
1403 {
1404         char            *mo_name;       /* long name of milter option */
1405         unsigned char   mo_code;        /* code for option */
1406 } MilterOptTab[] =
1407 {
1408 # define MO_MACROS_CONNECT              0x01
1409         { "macros.connect",             MO_MACROS_CONNECT               },
1410 # define MO_MACROS_HELO                 0x02
1411         { "macros.helo",                MO_MACROS_HELO                  },
1412 # define MO_MACROS_ENVFROM              0x03
1413         { "macros.envfrom",             MO_MACROS_ENVFROM               },
1414 # define MO_MACROS_ENVRCPT              0x04
1415         { "macros.envrcpt",             MO_MACROS_ENVRCPT               },
1416 # define MO_LOGLEVEL                    0x05
1417         { "loglevel",                   MO_LOGLEVEL                     },
1418         { NULL,                         0                               },
1419 };
1420
1421 void
1422 milter_set_option(name, val, sticky)
1423         char *name;
1424         char *val;
1425         bool sticky;
1426 {
1427         int nummac = 0;
1428         register struct milteropt *mo;
1429         char *p;
1430         char **macros = NULL;
1431
1432         if (tTd(37, 2) || tTd(64, 5))
1433                 sm_dprintf("milter_set_option(%s = %s)", name, val);
1434
1435         if (name == NULL)
1436         {
1437                 syserr("milter_set_option: invalid Milter option, must specify suboption");
1438                 return;
1439         }
1440
1441         for (mo = MilterOptTab; mo->mo_name != NULL; mo++)
1442         {
1443                 if (sm_strcasecmp(mo->mo_name, name) == 0)
1444                         break;
1445         }
1446
1447         if (mo->mo_name == NULL)
1448         {
1449                 syserr("milter_set_option: invalid Milter option %s", name);
1450                 return;
1451         }
1452
1453         /*
1454         **  See if this option is preset for us.
1455         */
1456
1457         if (!sticky && bitnset(mo->mo_code, StickyMilterOpt))
1458         {
1459                 if (tTd(37, 2) || tTd(64,5))
1460                         sm_dprintf(" (ignored)\n");
1461                 return;
1462         }
1463
1464         if (tTd(37, 2) || tTd(64,5))
1465                 sm_dprintf("\n");
1466
1467         switch (mo->mo_code)
1468         {
1469           case MO_LOGLEVEL:
1470                 MilterLogLevel = atoi(val);
1471                 break;
1472
1473           case MO_MACROS_CONNECT:
1474                 if (macros == NULL)
1475                         macros = MilterConnectMacros;
1476                 /* FALLTHROUGH */
1477
1478           case MO_MACROS_HELO:
1479                 if (macros == NULL)
1480                         macros = MilterHeloMacros;
1481                 /* FALLTHROUGH */
1482
1483           case MO_MACROS_ENVFROM:
1484                 if (macros == NULL)
1485                         macros = MilterEnvFromMacros;
1486                 /* FALLTHROUGH */
1487
1488           case MO_MACROS_ENVRCPT:
1489                 if (macros == NULL)
1490                         macros = MilterEnvRcptMacros;
1491
1492                 p = newstr(val);
1493                 while (*p != '\0')
1494                 {
1495                         char *macro;
1496
1497                         /* Skip leading commas, spaces */
1498                         while (*p != '\0' &&
1499                                (*p == ',' || (isascii(*p) && isspace(*p))))
1500                                 p++;
1501
1502                         if (*p == '\0')
1503                                 break;
1504
1505                         /* Find end of macro */
1506                         macro = p;
1507                         while (*p != '\0' && *p != ',' &&
1508                                isascii(*p) && !isspace(*p))
1509                                 p++;
1510                         if (*p != '\0')
1511                                 *p++ = '\0';
1512
1513                         if (nummac >= MAXFILTERMACROS)
1514                         {
1515                                 syserr("milter_set_option: too many macros in Milter.%s (max %d)",
1516                                        name, MAXFILTERMACROS);
1517                                 macros[nummac] = NULL;
1518                                 break;
1519                         }
1520                         macros[nummac++] = macro;
1521                 }
1522                 macros[nummac] = NULL;
1523                 break;
1524
1525           default:
1526                 syserr("milter_set_option: invalid Milter option %s", name);
1527                 break;
1528         }
1529         if (sticky)
1530                 setbitn(mo->mo_code, StickyMilterOpt);
1531 }
1532 /*
1533 **  MILTER_REOPEN_DF -- open & truncate the data file (for replbody)
1534 **
1535 **      Parameters:
1536 **              e -- current envelope.
1537 **
1538 **      Returns:
1539 **              0 if succesful, -1 otherwise
1540 */
1541
1542 static int
1543 milter_reopen_df(e)
1544         ENVELOPE *e;
1545 {
1546         char dfname[MAXPATHLEN];
1547
1548         (void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), sizeof dfname);
1549
1550         /*
1551         **  In SuperSafe == SAFE_REALLY mode, e->e_dfp is a read-only FP so
1552         **  close and reopen writable (later close and reopen
1553         **  read only again).
1554         **
1555         **  In SuperSafe != SAFE_REALLY mode, e->e_dfp still points at the
1556         **  buffered file I/O descriptor, still open for writing
1557         **  so there isn't as much work to do, just truncate it
1558         **  and go.
1559         */
1560
1561         if (SuperSafe == SAFE_REALLY)
1562         {
1563                 /* close read-only data file */
1564                 if (bitset(EF_HAS_DF, e->e_flags) && e->e_dfp != NULL)
1565                 {
1566                         (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT);
1567                         e->e_flags &= ~EF_HAS_DF;
1568                 }
1569
1570                 /* open writable */
1571                 if ((e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname,
1572                                            SM_IO_RDWR, NULL)) == NULL)
1573                 {
1574                         MILTER_DF_ERROR("milter_reopen_df: sm_io_open %s: %s");
1575                         return -1;
1576                 }
1577         }
1578         else if (e->e_dfp == NULL)
1579         {
1580                 /* shouldn't happen */
1581                 errno = ENOENT;
1582                 MILTER_DF_ERROR("milter_reopen_df: NULL e_dfp (%s: %s)");
1583                 return -1;
1584         }
1585         return 0;
1586 }
1587 /*
1588 **  MILTER_RESET_DF -- re-open read-only the data file (for replbody)
1589 **
1590 **      Parameters:
1591 **              e -- current envelope.
1592 **
1593 **      Returns:
1594 **              0 if succesful, -1 otherwise
1595 */
1596
1597 static int
1598 milter_reset_df(e)
1599         ENVELOPE *e;
1600 {
1601         int afd;
1602         char dfname[MAXPATHLEN];
1603
1604         (void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), sizeof dfname);
1605
1606         if (sm_io_flush(e->e_dfp, SM_TIME_DEFAULT) != 0 ||
1607             sm_io_error(e->e_dfp))
1608         {
1609                 MILTER_DF_ERROR("milter_reset_df: error writing/flushing %s: %s");
1610                 return -1;
1611         }
1612         else if (SuperSafe != SAFE_REALLY)
1613         {
1614                 /* skip next few clauses */
1615                 /* EMPTY */
1616         }
1617         else if ((afd = sm_io_getinfo(e->e_dfp, SM_IO_WHAT_FD, NULL)) >= 0
1618                  && fsync(afd) < 0)
1619         {
1620                 MILTER_DF_ERROR("milter_reset_df: error sync'ing %s: %s");
1621                 return -1;
1622         }
1623         else if (sm_io_close(e->e_dfp, SM_TIME_DEFAULT) < 0)
1624         {
1625                 MILTER_DF_ERROR("milter_reset_df: error closing %s: %s");
1626                 return -1;
1627         }
1628         else if ((e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname,
1629                                         SM_IO_RDONLY, NULL)) == NULL)
1630         {
1631                 MILTER_DF_ERROR("milter_reset_df: error reopening %s: %s");
1632                 return -1;
1633         }
1634         else
1635                 e->e_flags |= EF_HAS_DF;
1636         return 0;
1637 }
1638 /*
1639 **  MILTER_CAN_DELRCPTS -- can any milter filters delete recipients?
1640 **
1641 **      Parameters:
1642 **              none
1643 **
1644 **      Returns:
1645 **              true if any filter deletes recipients, false otherwise
1646 */
1647
1648 bool
1649 milter_can_delrcpts()
1650 {
1651         bool can = false;
1652         int i;
1653
1654         if (tTd(64, 10))
1655                 sm_dprintf("milter_can_delrcpts:");
1656
1657         for (i = 0; InputFilters[i] != NULL; i++)
1658         {
1659                 struct milter *m = InputFilters[i];
1660
1661                 if (bitset(SMFIF_DELRCPT, m->mf_fflags))
1662                 {
1663                         can = true;
1664                         break;
1665                 }
1666         }
1667         if (tTd(64, 10))
1668                 sm_dprintf("%s\n", can ? "true" : "false");
1669
1670         return can;
1671 }
1672 /*
1673 **  MILTER_QUIT_FILTER -- close down a single filter
1674 **
1675 **      Parameters:
1676 **              m -- milter structure of filter to close down.
1677 **              e -- current envelope.
1678 **
1679 **      Returns:
1680 **              none
1681 */
1682
1683 static void
1684 milter_quit_filter(m, e)
1685         struct milter *m;
1686         ENVELOPE *e;
1687 {
1688         if (tTd(64, 10))
1689                 sm_dprintf("milter_quit_filter(%s)\n", m->mf_name);
1690         if (MilterLogLevel > 18)
1691                 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): quit filter",
1692                           m->mf_name);
1693
1694         /* Never replace error state */
1695         if (m->mf_state == SMFS_ERROR)
1696                 return;
1697
1698         if (m->mf_sock < 0 ||
1699             m->mf_state == SMFS_CLOSED ||
1700             m->mf_state == SMFS_READY)
1701         {
1702                 m->mf_sock = -1;
1703                 m->mf_state = SMFS_CLOSED;
1704                 return;
1705         }
1706
1707         (void) milter_write(m, SMFIC_QUIT, (char *) NULL, 0,
1708                             m->mf_timeout[SMFTO_WRITE], e);
1709         if (m->mf_sock >= 0)
1710         {
1711                 (void) close(m->mf_sock);
1712                 m->mf_sock = -1;
1713         }
1714         if (m->mf_state != SMFS_ERROR)
1715                 m->mf_state = SMFS_CLOSED;
1716 }
1717 /*
1718 **  MILTER_ABORT_FILTER -- tell filter to abort current message
1719 **
1720 **      Parameters:
1721 **              m -- milter structure of filter to abort.
1722 **              e -- current envelope.
1723 **
1724 **      Returns:
1725 **              none
1726 */
1727
1728 static void
1729 milter_abort_filter(m, e)
1730         struct milter *m;
1731         ENVELOPE *e;
1732 {
1733         if (tTd(64, 10))
1734                 sm_dprintf("milter_abort_filter(%s)\n", m->mf_name);
1735         if (MilterLogLevel > 10)
1736                 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): abort filter",
1737                           m->mf_name);
1738
1739         if (m->mf_sock < 0 ||
1740             m->mf_state != SMFS_INMSG)
1741                 return;
1742
1743         (void) milter_write(m, SMFIC_ABORT, (char *) NULL, 0,
1744                             m->mf_timeout[SMFTO_WRITE], e);
1745         if (m->mf_state != SMFS_ERROR)
1746                 m->mf_state = SMFS_DONE;
1747 }
1748 /*
1749 **  MILTER_SEND_MACROS -- provide macros to the filters
1750 **
1751 **      Parameters:
1752 **              m -- milter to send macros to.
1753 **              macros -- macros to send for filter smfi_getsymval().
1754 **              cmd -- which command the macros are associated with.
1755 **              e -- current envelope (for macro access).
1756 **
1757 **      Returns:
1758 **              none
1759 */
1760
1761 static void
1762 milter_send_macros(m, macros, cmd, e)
1763         struct milter *m;
1764         char **macros;
1765         char cmd;
1766         ENVELOPE *e;
1767 {
1768         int i;
1769         int mid;
1770         char *v;
1771         char *buf, *bp;
1772         char exp[MAXLINE];
1773         ssize_t s;
1774
1775         /* sanity check */
1776         if (macros == NULL || macros[0] == NULL)
1777                 return;
1778
1779         /* put together data */
1780         s = 1;                  /* for the command character */
1781         for (i = 0; macros[i] != NULL; i++)
1782         {
1783                 mid = macid(macros[i]);
1784                 if (mid == 0)
1785                         continue;
1786                 v = macvalue(mid, e);
1787                 if (v == NULL)
1788                         continue;
1789                 expand(v, exp, sizeof(exp), e);
1790                 s += strlen(macros[i]) + 1 + strlen(exp) + 1;
1791         }
1792
1793         if (s < 0)
1794                 return;
1795
1796         buf = (char *) xalloc(s);
1797         bp = buf;
1798         *bp++ = cmd;
1799         for (i = 0; macros[i] != NULL; i++)
1800         {
1801                 mid = macid(macros[i]);
1802                 if (mid == 0)
1803                         continue;
1804                 v = macvalue(mid, e);
1805                 if (v == NULL)
1806                         continue;
1807                 expand(v, exp, sizeof(exp), e);
1808
1809                 if (tTd(64, 10))
1810                         sm_dprintf("milter_send_macros(%s, %c): %s=%s\n",
1811                                 m->mf_name, cmd, macros[i], exp);
1812
1813                 (void) sm_strlcpy(bp, macros[i], s - (bp - buf));
1814                 bp += strlen(bp) + 1;
1815                 (void) sm_strlcpy(bp, exp, s - (bp - buf));
1816                 bp += strlen(bp) + 1;
1817         }
1818         (void) milter_write(m, SMFIC_MACRO, buf, s,
1819                             m->mf_timeout[SMFTO_WRITE], e);
1820         sm_free(buf); /* XXX */
1821 }
1822
1823 /*
1824 **  MILTER_SEND_COMMAND -- send a command and return the response for a filter
1825 **
1826 **      Parameters:
1827 **              m -- current milter filter
1828 **              command -- command to send.
1829 **              data -- optional command data.
1830 **              sz -- length of buf.
1831 **              e -- current envelope (for e->e_id).
1832 **              state -- return state word.
1833 **
1834 **      Returns:
1835 **              response string (may be NULL)
1836 */
1837
1838 static char *
1839 milter_send_command(m, command, data, sz, e, state)
1840         struct milter *m;
1841         char command;
1842         void *data;
1843         ssize_t sz;
1844         ENVELOPE *e;
1845         char *state;
1846 {
1847         char rcmd;
1848         ssize_t rlen;
1849         unsigned long skipflag;
1850         char *action;
1851         char *defresponse;
1852         char *response;
1853
1854         if (tTd(64, 10))
1855                 sm_dprintf("milter_send_command(%s): cmd %c len %ld\n",
1856                         m->mf_name, (char) command, (long) sz);
1857
1858         /* find skip flag and default failure */
1859         switch (command)
1860         {
1861           case SMFIC_CONNECT:
1862                 skipflag = SMFIP_NOCONNECT;
1863                 action = "connect";
1864                 defresponse = "554 Command rejected";
1865                 break;
1866
1867           case SMFIC_HELO:
1868                 skipflag = SMFIP_NOHELO;
1869                 action = "helo";
1870                 defresponse = "550 Command rejected";
1871                 break;
1872
1873           case SMFIC_MAIL:
1874                 skipflag = SMFIP_NOMAIL;
1875                 action = "mail";
1876                 defresponse = "550 5.7.1 Command rejected";
1877                 break;
1878
1879           case SMFIC_RCPT:
1880                 skipflag = SMFIP_NORCPT;
1881                 action = "rcpt";
1882                 defresponse = "550 5.7.1 Command rejected";
1883                 break;
1884
1885           case SMFIC_HEADER:
1886                 skipflag = SMFIP_NOHDRS;
1887                 action = "header";
1888                 defresponse = "550 5.7.1 Command rejected";
1889                 break;
1890
1891           case SMFIC_BODY:
1892                 skipflag = SMFIP_NOBODY;
1893                 action = "body";
1894                 defresponse = "554 5.7.1 Command rejected";
1895                 break;
1896
1897           case SMFIC_EOH:
1898                 skipflag = SMFIP_NOEOH;
1899                 action = "eoh";
1900                 defresponse = "550 5.7.1 Command rejected";
1901                 break;
1902
1903           case SMFIC_BODYEOB:
1904           case SMFIC_OPTNEG:
1905           case SMFIC_MACRO:
1906           case SMFIC_ABORT:
1907           case SMFIC_QUIT:
1908                 /* NOTE: not handled by milter_send_command() */
1909                 /* FALLTHROUGH */
1910
1911           default:
1912                 skipflag = 0;
1913                 action = "default";
1914                 defresponse = "550 5.7.1 Command rejected";
1915                 break;
1916         }
1917
1918         /* check if filter wants this command */
1919         if (skipflag != 0 &&
1920             bitset(skipflag, m->mf_pflags))
1921                 return NULL;
1922
1923         /* send the command to the filter */
1924         (void) milter_write(m, command, data, sz,
1925                             m->mf_timeout[SMFTO_WRITE], e);
1926         if (m->mf_state == SMFS_ERROR)
1927         {
1928                 MILTER_CHECK_ERROR(false, return NULL);
1929                 return NULL;
1930         }
1931
1932         /* get the response from the filter */
1933         response = milter_read(m, &rcmd, &rlen,
1934                                m->mf_timeout[SMFTO_READ], e);
1935         if (m->mf_state == SMFS_ERROR)
1936         {
1937                 MILTER_CHECK_ERROR(false, return NULL);
1938                 return NULL;
1939         }
1940
1941         if (tTd(64, 10))
1942                 sm_dprintf("milter_send_command(%s): returned %c\n",
1943                            m->mf_name, (char) rcmd);
1944
1945         switch (rcmd)
1946         {
1947           case SMFIR_REPLYCODE:
1948                 MILTER_CHECK_REPLYCODE(defresponse);
1949                 if (MilterLogLevel > 10)
1950                         sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, reject=%s",
1951                                   m->mf_name, action, response);
1952                 *state = rcmd;
1953                 break;
1954
1955           case SMFIR_REJECT:
1956                 if (MilterLogLevel > 10)
1957                         sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, reject",
1958                                   m->mf_name, action);
1959                 *state = rcmd;
1960                 break;
1961
1962           case SMFIR_DISCARD:
1963                 if (MilterLogLevel > 10)
1964                         sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, discard",
1965                                   m->mf_name, action);
1966                 *state = rcmd;
1967                 break;
1968
1969           case SMFIR_TEMPFAIL:
1970                 if (MilterLogLevel > 10)
1971                         sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, tempfail",
1972                                   m->mf_name, action);
1973                 *state = rcmd;
1974                 break;
1975
1976           case SMFIR_ACCEPT:
1977                 /* this filter is done with message/connection */
1978                 if (command == SMFIC_HELO ||
1979                     command == SMFIC_CONNECT)
1980                         m->mf_state = SMFS_CLOSABLE;
1981                 else
1982                         m->mf_state = SMFS_DONE;
1983                 if (MilterLogLevel > 10)
1984                         sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, accepted",
1985                                   m->mf_name, action);
1986                 break;
1987
1988           case SMFIR_CONTINUE:
1989                 /* if MAIL command is ok, filter is in message state */
1990                 if (command == SMFIC_MAIL)
1991                         m->mf_state = SMFS_INMSG;
1992                 if (MilterLogLevel > 12)
1993                         sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, continue",
1994                                   m->mf_name, action);
1995                 break;
1996
1997           default:
1998                 /* Invalid response to command */
1999                 if (MilterLogLevel > 0)
2000                         sm_syslog(LOG_ERR, e->e_id,
2001                                   "milter_send_command(%s): action=%s returned bogus response %c",
2002                                   m->mf_name, action, rcmd);
2003                 milter_error(m, e);
2004                 break;
2005         }
2006
2007         if (*state != SMFIR_REPLYCODE &&
2008             response != NULL)
2009         {
2010                 sm_free(response); /* XXX */
2011                 response = NULL;
2012         }
2013         return response;
2014 }
2015
2016 /*
2017 **  MILTER_COMMAND -- send a command and return the response for each filter
2018 **
2019 **      Parameters:
2020 **              command -- command to send.
2021 **              data -- optional command data.
2022 **              sz -- length of buf.
2023 **              macros -- macros to send for filter smfi_getsymval().
2024 **              e -- current envelope (for macro access).
2025 **              state -- return state word.
2026 **
2027 **      Returns:
2028 **              response string (may be NULL)
2029 */
2030
2031 static char *
2032 milter_command(command, data, sz, macros, e, state)
2033         char command;
2034         void *data;
2035         ssize_t sz;
2036         char **macros;
2037         ENVELOPE *e;
2038         char *state;
2039 {
2040         int i;
2041         char *response = NULL;
2042         time_t tn = 0;
2043
2044         if (tTd(64, 10))
2045                 sm_dprintf("milter_command: cmd %c len %ld\n",
2046                         (char) command, (long) sz);
2047
2048         *state = SMFIR_CONTINUE;
2049         for (i = 0; InputFilters[i] != NULL; i++)
2050         {
2051                 struct milter *m = InputFilters[i];
2052
2053                 /* previous problem? */
2054                 if (m->mf_state == SMFS_ERROR)
2055                 {
2056                         MILTER_CHECK_ERROR(false, continue);
2057                         break;
2058                 }
2059
2060                 /* sanity check */
2061                 if (m->mf_sock < 0 ||
2062                     (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG))
2063                         continue;
2064
2065                 /* send macros (regardless of whether we send command) */
2066                 if (macros != NULL && macros[0] != NULL)
2067                 {
2068                         milter_send_macros(m, macros, command, e);
2069                         if (m->mf_state == SMFS_ERROR)
2070                         {
2071                                 MILTER_CHECK_ERROR(false, continue);
2072                                 break;
2073                         }
2074                 }
2075
2076                 if (MilterLogLevel > 21)
2077                         tn = curtime();
2078
2079                 response = milter_send_command(m, command, data, sz, e, state);
2080
2081                 if (MilterLogLevel > 21)
2082                 {
2083                         /* log the time it took for the command per filter */
2084                         sm_syslog(LOG_INFO, e->e_id,
2085                                   "Milter (%s): time command (%c), %d",
2086                                   m->mf_name, command, (int) (tn - curtime()));
2087                 }
2088
2089                 if (*state != SMFIR_CONTINUE)
2090                         break;
2091         }
2092         return response;
2093 }
2094 /*
2095 **  MILTER_NEGOTIATE -- get version and flags from filter
2096 **
2097 **      Parameters:
2098 **              m -- milter filter structure.
2099 **              e -- current envelope.
2100 **
2101 **      Returns:
2102 **              0 on success, -1 otherwise
2103 */
2104
2105 static int
2106 milter_negotiate(m, e)
2107         struct milter *m;
2108         ENVELOPE *e;
2109 {
2110         char rcmd;
2111         mi_int32 fvers;
2112         mi_int32 fflags;
2113         mi_int32 pflags;
2114         char *response;
2115         ssize_t rlen;
2116         char data[MILTER_OPTLEN];
2117
2118         /* sanity check */
2119         if (m->mf_sock < 0 || m->mf_state != SMFS_OPEN)
2120         {
2121                 if (MilterLogLevel > 0)
2122                         sm_syslog(LOG_ERR, e->e_id,
2123                                   "Milter (%s): negotiate, impossible state",
2124                                   m->mf_name);
2125                 milter_error(m, e);
2126                 return -1;
2127         }
2128
2129         fvers = htonl(SMFI_VERSION);
2130         fflags = htonl(SMFI_CURR_ACTS);
2131         pflags = htonl(SMFI_CURR_PROT);
2132         (void) memcpy(data, (char *) &fvers, MILTER_LEN_BYTES);
2133         (void) memcpy(data + MILTER_LEN_BYTES,
2134                       (char *) &fflags, MILTER_LEN_BYTES);
2135         (void) memcpy(data + (MILTER_LEN_BYTES * 2),
2136                       (char *) &pflags, MILTER_LEN_BYTES);
2137         (void) milter_write(m, SMFIC_OPTNEG, data, sizeof data,
2138                             m->mf_timeout[SMFTO_WRITE], e);
2139
2140         if (m->mf_state == SMFS_ERROR)
2141                 return -1;
2142
2143         response = milter_read(m, &rcmd, &rlen, m->mf_timeout[SMFTO_READ], e);
2144         if (m->mf_state == SMFS_ERROR)
2145                 return -1;
2146
2147         if (rcmd != SMFIC_OPTNEG)
2148         {
2149                 if (tTd(64, 5))
2150                         sm_dprintf("milter_negotiate(%s): returned %c instead of %c\n",
2151                                 m->mf_name, rcmd, SMFIC_OPTNEG);
2152                 if (MilterLogLevel > 0)
2153                         sm_syslog(LOG_ERR, e->e_id,
2154                                   "Milter (%s): negotiate: returned %c instead of %c",
2155                                   m->mf_name, rcmd, SMFIC_OPTNEG);
2156                 if (response != NULL)
2157                         sm_free(response); /* XXX */
2158                 milter_error(m, e);
2159                 return -1;
2160         }
2161
2162         /* Make sure we have enough bytes for the version */
2163         if (response == NULL || rlen < MILTER_LEN_BYTES)
2164         {
2165                 if (tTd(64, 5))
2166                         sm_dprintf("milter_negotiate(%s): did not return valid info\n",
2167                                 m->mf_name);
2168                 if (MilterLogLevel > 0)
2169                         sm_syslog(LOG_ERR, e->e_id,
2170                                   "Milter (%s): negotiate: did not return valid info",
2171                                   m->mf_name);
2172                 if (response != NULL)
2173                         sm_free(response); /* XXX */
2174                 milter_error(m, e);
2175                 return -1;
2176         }
2177
2178         /* extract information */
2179         (void) memcpy((char *) &fvers, response, MILTER_LEN_BYTES);
2180
2181         /* Now make sure we have enough for the feature bitmap */
2182         if (rlen != MILTER_OPTLEN)
2183         {
2184                 if (tTd(64, 5))
2185                         sm_dprintf("milter_negotiate(%s): did not return enough info\n",
2186                                 m->mf_name);
2187                 if (MilterLogLevel > 0)
2188                         sm_syslog(LOG_ERR, e->e_id,
2189                                   "Milter (%s): negotiate: did not return enough info",
2190                                   m->mf_name);
2191                 if (response != NULL)
2192                         sm_free(response); /* XXX */
2193                 milter_error(m, e);
2194                 return -1;
2195         }
2196
2197         (void) memcpy((char *) &fflags, response + MILTER_LEN_BYTES,
2198                       MILTER_LEN_BYTES);
2199         (void) memcpy((char *) &pflags, response + (MILTER_LEN_BYTES * 2),
2200                       MILTER_LEN_BYTES);
2201         sm_free(response); /* XXX */
2202         response = NULL;
2203
2204         m->mf_fvers = ntohl(fvers);
2205         m->mf_fflags = ntohl(fflags);
2206         m->mf_pflags = ntohl(pflags);
2207
2208         /* check for version compatibility */
2209         if (m->mf_fvers == 1 ||
2210             m->mf_fvers > SMFI_VERSION)
2211         {
2212                 if (tTd(64, 5))
2213                         sm_dprintf("milter_negotiate(%s): version %d != MTA milter version %d\n",
2214                                 m->mf_name, m->mf_fvers, SMFI_VERSION);
2215                 if (MilterLogLevel > 0)
2216                         sm_syslog(LOG_ERR, e->e_id,
2217                                   "Milter (%s): negotiate: version %d != MTA milter version %d",
2218                                   m->mf_name, m->mf_fvers, SMFI_VERSION);
2219                 milter_error(m, e);
2220                 return -1;
2221         }
2222
2223         /* check for filter feature mismatch */
2224         if ((m->mf_fflags & SMFI_CURR_ACTS) != m->mf_fflags)
2225         {
2226                 if (tTd(64, 5))
2227                         sm_dprintf("milter_negotiate(%s): filter abilities 0x%x != MTA milter abilities 0x%lx\n",
2228                                 m->mf_name, m->mf_fflags,
2229                                 SMFI_CURR_ACTS);
2230                 if (MilterLogLevel > 0)
2231                         sm_syslog(LOG_ERR, e->e_id,
2232                                   "Milter (%s): negotiate: filter abilities 0x%x != MTA milter abilities 0x%lx",
2233                                   m->mf_name, m->mf_fflags,
2234                                   (unsigned long) SMFI_CURR_ACTS);
2235                 milter_error(m, e);
2236                 return -1;
2237         }
2238
2239         /* check for protocol feature mismatch */
2240         if ((m->mf_pflags & SMFI_CURR_PROT) != m->mf_pflags)
2241         {
2242                 if (tTd(64, 5))
2243                         sm_dprintf("milter_negotiate(%s): protocol abilities 0x%x != MTA milter abilities 0x%lx\n",
2244                                 m->mf_name, m->mf_pflags,
2245                                 (unsigned long) SMFI_CURR_PROT);
2246                 if (MilterLogLevel > 0)
2247                         sm_syslog(LOG_ERR, e->e_id,
2248                                   "Milter (%s): negotiate: protocol abilities 0x%x != MTA milter abilities 0x%lx",
2249                                   m->mf_name, m->mf_pflags,
2250                                   (unsigned long) SMFI_CURR_PROT);
2251                 milter_error(m, e);
2252                 return -1;
2253         }
2254
2255         if (tTd(64, 5))
2256                 sm_dprintf("milter_negotiate(%s): version %u, fflags 0x%x, pflags 0x%x\n",
2257                         m->mf_name, m->mf_fvers, m->mf_fflags, m->mf_pflags);
2258         return 0;
2259 }
2260 /*
2261 **  MILTER_PER_CONNECTION_CHECK -- checks on per-connection commands
2262 **
2263 **      Reduce code duplication by putting these checks in one place
2264 **
2265 **      Parameters:
2266 **              e -- current envelope.
2267 **
2268 **      Returns:
2269 **              none
2270 */
2271
2272 static void
2273 milter_per_connection_check(e)
2274         ENVELOPE *e;
2275 {
2276         int i;
2277
2278         /* see if we are done with any of the filters */
2279         for (i = 0; InputFilters[i] != NULL; i++)
2280         {
2281                 struct milter *m = InputFilters[i];
2282
2283                 if (m->mf_state == SMFS_CLOSABLE)
2284                         milter_quit_filter(m, e);
2285         }
2286 }
2287 /*
2288 **  MILTER_ERROR -- Put a milter filter into error state
2289 **
2290 **      Parameters:
2291 **              m -- the broken filter.
2292 **
2293 **      Returns:
2294 **              none
2295 */
2296
2297 static void
2298 milter_error(m, e)
2299         struct milter *m;
2300         ENVELOPE *e;
2301 {
2302         /*
2303         **  We could send a quit here but
2304         **  we may have gotten here due to
2305         **  an I/O error so we don't want
2306         **  to try to make things worse.
2307         */
2308
2309         if (m->mf_sock >= 0)
2310         {
2311                 (void) close(m->mf_sock);
2312                 m->mf_sock = -1;
2313         }
2314         m->mf_state = SMFS_ERROR;
2315
2316         if (MilterLogLevel > 0)
2317                 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): to error state",
2318                           m->mf_name);
2319 }
2320 /*
2321 **  MILTER_HEADERS -- send headers to a single milter filter
2322 **
2323 **      Parameters:
2324 **              m -- current filter.
2325 **              e -- current envelope.
2326 **              state -- return state from response.
2327 **
2328 **      Returns:
2329 **              response string (may be NULL)
2330 */
2331
2332 static char *
2333 milter_headers(m, e, state)
2334         struct milter *m;
2335         ENVELOPE *e;
2336         char *state;
2337 {
2338         char *response = NULL;
2339         HDR *h;
2340
2341         if (MilterLogLevel > 17)
2342                 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): headers, send",
2343                           m->mf_name);
2344
2345         for (h = e->e_header; h != NULL; h = h->h_link)
2346         {
2347                 char *buf;
2348                 ssize_t s;
2349
2350                 /* don't send over deleted headers */
2351                 if (h->h_value == NULL)
2352                 {
2353                         /* strip H_USER so not counted in milter_chgheader() */
2354                         h->h_flags &= ~H_USER;
2355                         continue;
2356                 }
2357
2358                 /* skip auto-generated */
2359                 if (!bitset(H_USER, h->h_flags))
2360                         continue;
2361
2362                 if (tTd(64, 10))
2363                         sm_dprintf("milter_headers: %s: %s\n",
2364                                 h->h_field, h->h_value);
2365                 if (MilterLogLevel > 21)
2366                         sm_syslog(LOG_INFO, e->e_id, "Milter (%s): header, %s",
2367                                   m->mf_name, h->h_field);
2368
2369                 s = strlen(h->h_field) + 1 + strlen(h->h_value) + 1;
2370                 if (s < 0)
2371                         continue;
2372                 buf = (char *) xalloc(s);
2373                 (void) sm_snprintf(buf, s, "%s%c%s",
2374                         h->h_field, '\0', h->h_value);
2375
2376                 /* send it over */
2377                 response = milter_send_command(m, SMFIC_HEADER, buf,
2378                                                s, e, state);
2379                 sm_free(buf); /* XXX */
2380                 if (m->mf_state == SMFS_ERROR ||
2381                     m->mf_state == SMFS_DONE ||
2382                     *state != SMFIR_CONTINUE)
2383                         break;
2384         }
2385         if (MilterLogLevel > 17)
2386                 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): headers, sent",
2387                           m->mf_name);
2388         return response;
2389 }
2390 /*
2391 **  MILTER_BODY -- send the body to a filter
2392 **
2393 **      Parameters:
2394 **              m -- current filter.
2395 **              e -- current envelope.
2396 **              state -- return state from response.
2397 **
2398 **      Returns:
2399 **              response string (may be NULL)
2400 */
2401
2402 static char *
2403 milter_body(m, e, state)
2404         struct milter *m;
2405         ENVELOPE *e;
2406         char *state;
2407 {
2408         char bufchar = '\0';
2409         char prevchar = '\0';
2410         int c;
2411         char *response = NULL;
2412         char *bp;
2413         char buf[MILTER_CHUNK_SIZE];
2414
2415         if (tTd(64, 10))
2416                 sm_dprintf("milter_body\n");
2417
2418         if (bfrewind(e->e_dfp) < 0)
2419         {
2420                 ExitStat = EX_IOERR;
2421                 *state = SMFIR_TEMPFAIL;
2422                 syserr("milter_body: %s/%cf%s: rewind error",
2423                        qid_printqueue(e->e_qgrp, e->e_qdir),
2424                        DATAFL_LETTER, e->e_id);
2425                 return NULL;
2426         }
2427
2428         if (MilterLogLevel > 17)
2429                 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): body, send",
2430                           m->mf_name);
2431         bp = buf;
2432         while ((c = sm_io_getc(e->e_dfp, SM_TIME_DEFAULT)) != SM_IO_EOF)
2433         {
2434                 /*  Change LF to CRLF */
2435                 if (c == '\n')
2436                 {
2437                         /* Not a CRLF already? */
2438                         if (prevchar != '\r')
2439                         {
2440                                 /* Room for CR now? */
2441                                 if (bp + 2 > &buf[sizeof buf])
2442                                 {
2443                                         /* No room, buffer LF */
2444                                         bufchar = c;
2445
2446                                         /* and send CR now */
2447                                         c = '\r';
2448                                 }
2449                                 else
2450                                 {
2451                                         /* Room to do it now */
2452                                         *bp++ = '\r';
2453                                         prevchar = '\r';
2454                                 }
2455                         }
2456                 }
2457                 *bp++ = (char) c;
2458                 prevchar = c;
2459                 if (bp >= &buf[sizeof buf])
2460                 {
2461                         /* send chunk */
2462                         response = milter_send_command(m, SMFIC_BODY, buf,
2463                                                        bp - buf, e, state);
2464                         bp = buf;
2465                         if (bufchar != '\0')
2466                         {
2467                                 *bp++ = bufchar;
2468                                 bufchar = '\0';
2469                                 prevchar = bufchar;
2470                         }
2471                 }
2472                 if (m->mf_state == SMFS_ERROR ||
2473                     m->mf_state == SMFS_DONE ||
2474                     *state != SMFIR_CONTINUE)
2475                         break;
2476         }
2477
2478         /* check for read errors */
2479         if (sm_io_error(e->e_dfp))
2480         {
2481                 ExitStat = EX_IOERR;
2482                 if (*state == SMFIR_CONTINUE ||
2483                     *state == SMFIR_ACCEPT)
2484                 {
2485                         *state = SMFIR_TEMPFAIL;
2486                         if (response != NULL)
2487                         {
2488                                 sm_free(response); /* XXX */
2489                                 response = NULL;
2490                         }
2491                 }
2492                 syserr("milter_body: %s/%cf%s: read error",
2493                        qid_printqueue(e->e_qgrp, e->e_qdir),
2494                        DATAFL_LETTER, e->e_id);
2495                 return response;
2496         }
2497
2498         /* send last body chunk */
2499         if (bp > buf &&
2500             m->mf_state != SMFS_ERROR &&
2501             m->mf_state != SMFS_DONE &&
2502             *state == SMFIR_CONTINUE)
2503         {
2504                 /* send chunk */
2505                 response = milter_send_command(m, SMFIC_BODY, buf, bp - buf,
2506                                                e, state);
2507                 bp = buf;
2508         }
2509         if (MilterLogLevel > 17)
2510                 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): body, sent",
2511                           m->mf_name);
2512         return response;
2513 }
2514
2515 /*
2516 **  Actions
2517 */
2518
2519 /*
2520 **  MILTER_ADDHEADER -- Add the supplied header to the message
2521 **
2522 **      Parameters:
2523 **              response -- encoded form of header/value.
2524 **              rlen -- length of response.
2525 **              e -- current envelope.
2526 **
2527 **      Returns:
2528 **              none
2529 */
2530
2531 static void
2532 milter_addheader(response, rlen, e)
2533         char *response;
2534         ssize_t rlen;
2535         ENVELOPE *e;
2536 {
2537         char *val;
2538         HDR *h;
2539
2540         if (tTd(64, 10))
2541                 sm_dprintf("milter_addheader: ");
2542
2543         /* sanity checks */
2544         if (response == NULL)
2545         {
2546                 if (tTd(64, 10))
2547                         sm_dprintf("NULL response\n");
2548                 return;
2549         }
2550
2551         if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen)
2552         {
2553                 if (tTd(64, 10))
2554                         sm_dprintf("didn't follow protocol (total len)\n");
2555                 return;
2556         }
2557
2558         /* Find separating NUL */
2559         val = response + strlen(response) + 1;
2560
2561         /* another sanity check */
2562         if (strlen(response) + strlen(val) + 2 != (size_t) rlen)
2563         {
2564                 if (tTd(64, 10))
2565                         sm_dprintf("didn't follow protocol (part len)\n");
2566                 return;
2567         }
2568
2569         if (*response == '\0')
2570         {
2571                 if (tTd(64, 10))
2572                         sm_dprintf("empty field name\n");
2573                 return;
2574         }
2575
2576         for (h = e->e_header; h != NULL; h = h->h_link)
2577         {
2578                 if (sm_strcasecmp(h->h_field, response) == 0 &&
2579                     !bitset(H_USER, h->h_flags) &&
2580                     !bitset(H_TRACE, h->h_flags))
2581                         break;
2582         }
2583
2584         /* add to e_msgsize */
2585         e->e_msgsize += strlen(response) + 2 + strlen(val);
2586
2587         if (h != NULL)
2588         {
2589                 if (tTd(64, 10))
2590                         sm_dprintf("Replace default header %s value with %s\n",
2591                                    h->h_field, val);
2592                 if (MilterLogLevel > 8)
2593                         sm_syslog(LOG_INFO, e->e_id,
2594                                   "Milter change: default header %s value with %s",
2595                                   h->h_field, val);
2596                 h->h_value = newstr(val);
2597                 h->h_flags |= H_USER;
2598         }
2599         else
2600         {
2601                 if (tTd(64, 10))
2602                         sm_dprintf("Add %s: %s\n", response, val);
2603                 if (MilterLogLevel > 8)
2604                         sm_syslog(LOG_INFO, e->e_id, "Milter add: header: %s: %s",
2605                                   response, val);
2606                 addheader(newstr(response), val, H_USER, e);
2607         }
2608 }
2609 /*
2610 **  MILTER_CHANGEHEADER -- Change the supplied header in the message
2611 **
2612 **      Parameters:
2613 **              response -- encoded form of header/index/value.
2614 **              rlen -- length of response.
2615 **              e -- current envelope.
2616 **
2617 **      Returns:
2618 **              none
2619 */
2620
2621 static void
2622 milter_changeheader(response, rlen, e)
2623         char *response;
2624         ssize_t rlen;
2625         ENVELOPE *e;
2626 {
2627         mi_int32 i, index;
2628         char *field, *val;
2629         HDR *h, *sysheader;
2630
2631         if (tTd(64, 10))
2632                 sm_dprintf("milter_changeheader: ");
2633
2634         /* sanity checks */
2635         if (response == NULL)
2636         {
2637                 if (tTd(64, 10))
2638                         sm_dprintf("NULL response\n");
2639                 return;
2640         }
2641
2642         if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen)
2643         {
2644                 if (tTd(64, 10))
2645                         sm_dprintf("didn't follow protocol (total len)\n");
2646                 return;
2647         }
2648
2649         /* Find separating NUL */
2650         (void) memcpy((char *) &i, response, MILTER_LEN_BYTES);
2651         index = ntohl(i);
2652         field = response + MILTER_LEN_BYTES;
2653         val = field + strlen(field) + 1;
2654
2655         /* another sanity check */
2656         if (MILTER_LEN_BYTES + strlen(field) + 1 +
2657             strlen(val) + 1 != (size_t) rlen)
2658         {
2659                 if (tTd(64, 10))
2660                         sm_dprintf("didn't follow protocol (part len)\n");
2661                 return;
2662         }
2663
2664         if (*field == '\0')
2665         {
2666                 if (tTd(64, 10))
2667                         sm_dprintf("empty field name\n");
2668                 return;
2669         }
2670
2671         sysheader = NULL;
2672         for (h = e->e_header; h != NULL; h = h->h_link)
2673         {
2674                 if (sm_strcasecmp(h->h_field, field) == 0)
2675                 {
2676                         if (bitset(H_USER, h->h_flags) &&
2677                             --index <= 0)
2678                         {
2679                                 sysheader = NULL;
2680                                 break;
2681                         }
2682                         else if (!bitset(H_USER, h->h_flags) &&
2683                                  !bitset(H_TRACE, h->h_flags))
2684                         {
2685                                 /*
2686                                 **  DRUMS msg-fmt draft says can only have
2687                                 **  multiple occurences of trace fields,
2688                                 **  so make sure we replace any non-trace,
2689                                 **  non-user field.
2690                                 */
2691
2692                                 sysheader = h;
2693                         }
2694                 }
2695         }
2696
2697         /* if not found as user-provided header at index, use sysheader */
2698         if (h == NULL)
2699                 h = sysheader;
2700
2701         if (h == NULL)
2702         {
2703                 if (*val == '\0')
2704                 {
2705                         if (tTd(64, 10))
2706                                 sm_dprintf("Delete (noop) %s:\n", field);
2707                 }
2708                 else
2709                 {
2710                         /* treat modify value with no existing header as add */
2711                         if (tTd(64, 10))
2712                                 sm_dprintf("Add %s: %s\n", field, val);
2713                         addheader(newstr(field), val, H_USER, e);
2714                 }
2715                 return;
2716         }
2717
2718         if (tTd(64, 10))
2719         {
2720                 if (*val == '\0')
2721                 {
2722                         sm_dprintf("Delete%s %s: %s\n",
2723                                    h == sysheader ? " (default header)" : "",
2724                                    field,
2725                                    h->h_value == NULL ? "<NULL>" : h->h_value);
2726                 }
2727                 else
2728                 {
2729                         sm_dprintf("Change%s %s: from %s to %s\n",
2730                                    h == sysheader ? " (default header)" : "",
2731                                    field,
2732                                    h->h_value == NULL ? "<NULL>" : h->h_value,
2733                                    val);
2734                 }
2735         }
2736
2737         if (MilterLogLevel > 8)
2738         {
2739                 if (*val == '\0')
2740                 {
2741                         sm_syslog(LOG_INFO, e->e_id,
2742                                   "Milter delete: header %s %s: %s",
2743                                   h == sysheader ? " (default header)" : "",
2744                                   field,
2745                                   h->h_value == NULL ? "<NULL>" : h->h_value);
2746                 }
2747                 else
2748                 {
2749                         sm_syslog(LOG_INFO, e->e_id,
2750                                   "Milter change: header %s %s: from %s to %s",
2751                                   h == sysheader ? " (default header)" : "",
2752                                   field,
2753                                   h->h_value == NULL ? "<NULL>" : h->h_value,
2754                                   val);
2755                 }
2756         }
2757
2758         if (h != sysheader && h->h_value != NULL)
2759         {
2760                 size_t l;
2761
2762                 l = strlen(h->h_value);
2763                 if (l > e->e_msgsize)
2764                         e->e_msgsize = 0;
2765                 else
2766                         e->e_msgsize -= l;
2767                 /* rpool, don't free: sm_free(h->h_value); XXX */
2768         }
2769
2770         if (*val == '\0')
2771         {
2772                 /* Remove "Field: " from message size */
2773                 if (h != sysheader)
2774                 {
2775                         size_t l;
2776
2777                         l = strlen(h->h_field) + 2;
2778                         if (l > e->e_msgsize)
2779                                 e->e_msgsize = 0;
2780                         else
2781                                 e->e_msgsize -= l;
2782                 }
2783                 h->h_value = NULL;
2784         }
2785         else
2786         {
2787                 h->h_value = newstr(val);
2788                 h->h_flags |= H_USER;
2789                 e->e_msgsize += strlen(h->h_value);
2790         }
2791 }
2792 /*
2793 **  MILTER_ADDRCPT -- Add the supplied recipient to the message
2794 **
2795 **      Parameters:
2796 **              response -- encoded form of recipient address.
2797 **              rlen -- length of response.
2798 **              e -- current envelope.
2799 **
2800 **      Returns:
2801 **              none
2802 */
2803
2804 static void
2805 milter_addrcpt(response, rlen, e)
2806         char *response;
2807         ssize_t rlen;
2808         ENVELOPE *e;
2809 {
2810         if (tTd(64, 10))
2811                 sm_dprintf("milter_addrcpt: ");
2812
2813         /* sanity checks */
2814         if (response == NULL)
2815         {
2816                 if (tTd(64, 10))
2817                         sm_dprintf("NULL response\n");
2818                 return;
2819         }
2820
2821         if (*response == '\0' ||
2822             strlen(response) + 1 != (size_t) rlen)
2823         {
2824                 if (tTd(64, 10))
2825                         sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n",
2826                                    (int) strlen(response), (int) (rlen - 1));
2827                 return;
2828         }
2829
2830         if (tTd(64, 10))
2831                 sm_dprintf("%s\n", response);
2832         if (MilterLogLevel > 8)
2833                 sm_syslog(LOG_INFO, e->e_id, "Milter add: rcpt: %s", response);
2834         (void) sendtolist(response, NULLADDR, &e->e_sendqueue, 0, e);
2835         return;
2836 }
2837 /*
2838 **  MILTER_DELRCPT -- Delete the supplied recipient from the message
2839 **
2840 **      Parameters:
2841 **              response -- encoded form of recipient address.
2842 **              rlen -- length of response.
2843 **              e -- current envelope.
2844 **
2845 **      Returns:
2846 **              none
2847 */
2848
2849 static void
2850 milter_delrcpt(response, rlen, e)
2851         char *response;
2852         ssize_t rlen;
2853         ENVELOPE *e;
2854 {
2855         if (tTd(64, 10))
2856                 sm_dprintf("milter_delrcpt: ");
2857
2858         /* sanity checks */
2859         if (response == NULL)
2860         {
2861                 if (tTd(64, 10))
2862                         sm_dprintf("NULL response\n");
2863                 return;
2864         }
2865
2866         if (*response == '\0' ||
2867             strlen(response) + 1 != (size_t) rlen)
2868         {
2869                 if (tTd(64, 10))
2870                         sm_dprintf("didn't follow protocol (total len)\n");
2871                 return;
2872         }
2873
2874         if (tTd(64, 10))
2875                 sm_dprintf("%s\n", response);
2876         if (MilterLogLevel > 8)
2877                 sm_syslog(LOG_INFO, e->e_id, "Milter delete: rcpt %s",
2878                           response);
2879         (void) removefromlist(response, &e->e_sendqueue, e);
2880         return;
2881 }
2882 /*
2883 **  MILTER_REPLBODY -- Replace the current data file with new body
2884 **
2885 **      Parameters:
2886 **              response -- encoded form of new body.
2887 **              rlen -- length of response.
2888 **              newfilter -- if first time called by a new filter
2889 **              e -- current envelope.
2890 **
2891 **      Returns:
2892 **              0 upon success, -1 upon failure
2893 */
2894
2895 static int
2896 milter_replbody(response, rlen, newfilter, e)
2897         char *response;
2898         ssize_t rlen;
2899         bool newfilter;
2900         ENVELOPE *e;
2901 {
2902         static char prevchar;
2903         int i;
2904
2905         if (tTd(64, 10))
2906                 sm_dprintf("milter_replbody\n");
2907
2908         /* If a new filter, reset previous character and truncate data file */
2909         if (newfilter)
2910         {
2911                 off_t prevsize;
2912                 char dfname[MAXPATHLEN];
2913
2914                 (void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER),
2915                                   sizeof dfname);
2916
2917                 /* Reset prevchar */
2918                 prevchar = '\0';
2919
2920                 /* Get the current data file information */
2921                 prevsize = sm_io_getinfo(e->e_dfp, SM_IO_WHAT_SIZE, NULL);
2922                 if (prevsize < 0)
2923                         prevsize = 0;
2924
2925                 /* truncate current data file */
2926                 if (sm_io_getinfo(e->e_dfp, SM_IO_WHAT_ISTYPE, BF_FILE_TYPE))
2927                 {
2928                         if (sm_io_setinfo(e->e_dfp, SM_BF_TRUNCATE, NULL) < 0)
2929                         {
2930                                 MILTER_DF_ERROR("milter_replbody: sm_io truncate %s: %s");
2931                                 return -1;
2932                         }
2933                 }
2934                 else
2935                 {
2936                         int err;
2937
2938                         err = sm_io_error(e->e_dfp);
2939                         (void) sm_io_flush(e->e_dfp, SM_TIME_DEFAULT);
2940
2941                         /*
2942                         **  Clear error if tried to fflush()
2943                         **  a read-only file pointer and
2944                         **  there wasn't a previous error.
2945                         */
2946
2947                         if (err == 0)
2948                                 sm_io_clearerr(e->e_dfp);
2949
2950                         /* errno is set implicitly by fseek() before return */
2951                         err = sm_io_seek(e->e_dfp, SM_TIME_DEFAULT,
2952                                          0, SEEK_SET);
2953                         if (err < 0)
2954                         {
2955                                 MILTER_DF_ERROR("milter_replbody: sm_io_seek %s: %s");
2956                                 return -1;
2957                         }
2958 # if NOFTRUNCATE
2959                         /* XXX: Not much we can do except rewind it */
2960                         errno = EINVAL;
2961                         MILTER_DF_ERROR("milter_replbody: ftruncate not available on this platform (%s:%s)");
2962                         return -1;
2963 # else /* NOFTRUNCATE */
2964                         err = ftruncate(sm_io_getinfo(e->e_dfp,
2965                                                       SM_IO_WHAT_FD, NULL),
2966                                         0);
2967                         if (err < 0)
2968                         {
2969                                 MILTER_DF_ERROR("milter_replbody: sm_io ftruncate %s: %s");
2970                                 return -1;
2971                         }
2972 # endif /* NOFTRUNCATE */
2973                 }
2974
2975                 if (prevsize > e->e_msgsize)
2976                         e->e_msgsize = 0;
2977                 else
2978                         e->e_msgsize -= prevsize;
2979         }
2980
2981         if (newfilter && MilterLogLevel > 8)
2982                 sm_syslog(LOG_INFO, e->e_id, "Milter message: body replaced");
2983
2984         if (response == NULL)
2985         {
2986                 /* Flush the buffered '\r' */
2987                 if (prevchar == '\r')
2988                 {
2989                         (void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT, prevchar);
2990                         e->e_msgsize++;
2991                 }
2992                 return 0;
2993         }
2994
2995         for (i = 0; i < rlen; i++)
2996         {
2997                 /* Buffered char from last chunk */
2998                 if (i == 0 && prevchar == '\r')
2999                 {
3000                         /* Not CRLF, output prevchar */
3001                         if (response[i] != '\n')
3002                         {
3003                                 (void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT,
3004                                                   prevchar);
3005                                 e->e_msgsize++;
3006                         }
3007                         prevchar = '\0';
3008                 }
3009
3010                 /* Turn CRLF into LF */
3011                 if (response[i] == '\r')
3012                 {
3013                         /* check if at end of chunk */
3014                         if (i + 1 < rlen)
3015                         {
3016                                 /* If LF, strip CR */
3017                                 if (response[i + 1] == '\n')
3018                                         i++;
3019                         }
3020                         else
3021                         {
3022                                 /* check next chunk */
3023                                 prevchar = '\r';
3024                                 continue;
3025                         }
3026                 }
3027                 (void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT, response[i]);
3028                 e->e_msgsize++;
3029         }
3030         return 0;
3031 }
3032
3033 /*
3034 **  MTA callouts
3035 */
3036
3037 /*
3038 **  MILTER_INIT -- open and negotiate with all of the filters
3039 **
3040 **      Parameters:
3041 **              e -- current envelope.
3042 **              state -- return state from response.
3043 **
3044 **      Returns:
3045 **              true iff at least one filter is active
3046 */
3047
3048 /* ARGSUSED */
3049 bool
3050 milter_init(e, state)
3051         ENVELOPE *e;
3052         char *state;
3053 {
3054         int i;
3055
3056         if (tTd(64, 10))
3057                 sm_dprintf("milter_init\n");
3058
3059         *state = SMFIR_CONTINUE;
3060         if (InputFilters[0] == NULL)
3061         {
3062                 if (MilterLogLevel > 10)
3063                         sm_syslog(LOG_INFO, e->e_id,
3064                                   "Milter: no active filter");
3065                 return false;
3066         }
3067
3068         for (i = 0; InputFilters[i] != NULL; i++)
3069         {
3070                 struct milter *m = InputFilters[i];
3071
3072                 m->mf_sock = milter_open(m, false, e);
3073                 if (m->mf_state == SMFS_ERROR)
3074                 {
3075                         MILTER_CHECK_ERROR(true, continue);
3076                         break;
3077                 }
3078
3079                 if (m->mf_sock < 0 ||
3080                     milter_negotiate(m, e) < 0 ||
3081                     m->mf_state == SMFS_ERROR)
3082                 {
3083                         if (tTd(64, 5))
3084                                 sm_dprintf("milter_init(%s): failed to %s\n",
3085                                            m->mf_name,
3086                                            m->mf_sock < 0 ? "open" :
3087                                                             "negotiate");
3088                         if (MilterLogLevel > 0)
3089                                 sm_syslog(LOG_ERR, e->e_id,
3090                                           "Milter (%s): init failed to %s",
3091                                           m->mf_name,
3092                                           m->mf_sock < 0 ? "open" :
3093                                                            "negotiate");
3094
3095                         /* if negotation failure, close socket */
3096                         milter_error(m, e);
3097                         MILTER_CHECK_ERROR(true, continue);
3098                 }
3099                 if (MilterLogLevel > 9)
3100                         sm_syslog(LOG_INFO, e->e_id,
3101                                   "Milter (%s): init success to %s",
3102                                   m->mf_name,
3103                                   m->mf_sock < 0 ? "open" : "negotiate");
3104         }
3105
3106         /*
3107         **  If something temp/perm failed with one of the filters,
3108         **  we won't be using any of them, so clear any existing
3109         **  connections.
3110         */
3111
3112         if (*state != SMFIR_CONTINUE)
3113                 milter_quit(e);
3114
3115         return true;
3116 }
3117 /*
3118 **  MILTER_CONNECT -- send connection info to milter filters
3119 **
3120 **      Parameters:
3121 **              hostname -- hostname of remote machine.
3122 **              addr -- address of remote machine.
3123 **              e -- current envelope.
3124 **              state -- return state from response.
3125 **
3126 **      Returns:
3127 **              response string (may be NULL)
3128 */
3129
3130 char *
3131 milter_connect(hostname, addr, e, state)
3132         char *hostname;
3133         SOCKADDR addr;
3134         ENVELOPE *e;
3135         char *state;
3136 {
3137         char family;
3138         unsigned short port;
3139         char *buf, *bp;
3140         char *response;
3141         char *sockinfo = NULL;
3142         ssize_t s;
3143 # if NETINET6
3144         char buf6[INET6_ADDRSTRLEN];
3145 # endif /* NETINET6 */
3146
3147         if (tTd(64, 10))
3148                 sm_dprintf("milter_connect(%s)\n", hostname);
3149         if (MilterLogLevel > 9)
3150                 sm_syslog(LOG_INFO, e->e_id, "Milter: connect to filters");
3151
3152         /* gather data */
3153         switch (addr.sa.sa_family)
3154         {
3155 # if NETUNIX
3156           case AF_UNIX:
3157                 family = SMFIA_UNIX;
3158                 port = htons(0);
3159                 sockinfo = addr.sunix.sun_path;
3160                 break;
3161 # endif /* NETUNIX */
3162
3163 # if NETINET
3164           case AF_INET:
3165                 family = SMFIA_INET;
3166                 port = addr.sin.sin_port;
3167                 sockinfo = (char *) inet_ntoa(addr.sin.sin_addr);
3168                 break;
3169 # endif /* NETINET */
3170
3171 # if NETINET6
3172           case AF_INET6:
3173                 if (IN6_IS_ADDR_V4MAPPED(&addr.sin6.sin6_addr))
3174                         family = SMFIA_INET;
3175                 else
3176                         family = SMFIA_INET6;
3177                 port = addr.sin6.sin6_port;
3178                 sockinfo = anynet_ntop(&addr.sin6.sin6_addr, buf6,
3179                                        sizeof buf6);
3180                 if (sockinfo == NULL)
3181                         sockinfo = "";
3182                 break;
3183 # endif /* NETINET6 */
3184
3185           default:
3186                 family = SMFIA_UNKNOWN;
3187                 break;
3188         }
3189
3190         s = strlen(hostname) + 1 + sizeof(family);
3191         if (family != SMFIA_UNKNOWN)
3192                 s += sizeof(port) + strlen(sockinfo) + 1;
3193
3194         buf = (char *) xalloc(s);
3195         bp = buf;
3196
3197         /* put together data */
3198         (void) memcpy(bp, hostname, strlen(hostname));
3199         bp += strlen(hostname);
3200         *bp++ = '\0';
3201         (void) memcpy(bp, &family, sizeof family);
3202         bp += sizeof family;
3203         if (family != SMFIA_UNKNOWN)
3204         {
3205                 (void) memcpy(bp, &port, sizeof port);
3206                 bp += sizeof port;
3207
3208                 /* include trailing '\0' */
3209                 (void) memcpy(bp, sockinfo, strlen(sockinfo) + 1);
3210         }
3211
3212         response = milter_command(SMFIC_CONNECT, buf, s,
3213                                   MilterConnectMacros, e, state);
3214         sm_free(buf); /* XXX */
3215
3216         /*
3217         **  If this message connection is done for,
3218         **  close the filters.
3219         */
3220
3221         if (*state != SMFIR_CONTINUE)
3222         {
3223                 if (MilterLogLevel > 9)
3224                         sm_syslog(LOG_INFO, e->e_id, "Milter: connect, ending");
3225                 milter_quit(e);
3226         }
3227         else
3228                 milter_per_connection_check(e);
3229
3230         /*
3231         **  SMFIR_REPLYCODE can't work with connect due to
3232         **  the requirements of SMTP.  Therefore, ignore the
3233         **  reply code text but keep the state it would reflect.
3234         */
3235
3236         if (*state == SMFIR_REPLYCODE)
3237         {
3238                 if (response != NULL &&
3239                     *response == '4')
3240                 {
3241 #if _FFR_MILTER_421
3242                         if (strncmp(response, "421 ", 4) == 0)
3243                                 *state = SMFIR_SHUTDOWN;
3244                         else
3245 #endif /* _FFR_MILTER_421 */
3246                                 *state = SMFIR_TEMPFAIL;
3247                 }
3248                 else
3249                         *state = SMFIR_REJECT;
3250                 if (response != NULL)
3251                 {
3252                         sm_free(response); /* XXX */
3253                         response = NULL;
3254                 }
3255         }
3256         return response;
3257 }
3258 /*
3259 **  MILTER_HELO -- send SMTP HELO/EHLO command info to milter filters
3260 **
3261 **      Parameters:
3262 **              helo -- argument to SMTP HELO/EHLO command.
3263 **              e -- current envelope.
3264 **              state -- return state from response.
3265 **
3266 **      Returns:
3267 **              response string (may be NULL)
3268 */
3269
3270 char *
3271 milter_helo(helo, e, state)
3272         char *helo;
3273         ENVELOPE *e;
3274         char *state;
3275 {
3276         int i;
3277         char *response;
3278
3279         if (tTd(64, 10))
3280                 sm_dprintf("milter_helo(%s)\n", helo);
3281
3282         /* HELO/EHLO can come at any point */
3283         for (i = 0; InputFilters[i] != NULL; i++)
3284         {
3285                 struct milter *m = InputFilters[i];
3286
3287                 switch (m->mf_state)
3288                 {
3289                   case SMFS_INMSG:
3290                         /* abort in message filters */
3291                         milter_abort_filter(m, e);
3292                         /* FALLTHROUGH */
3293
3294                   case SMFS_DONE:
3295                         /* reset done filters */
3296                         m->mf_state = SMFS_OPEN;
3297                         break;
3298                 }
3299         }
3300
3301         response = milter_command(SMFIC_HELO, helo, strlen(helo) + 1,
3302                                   MilterHeloMacros, e, state);
3303         milter_per_connection_check(e);
3304         return response;
3305 }
3306 /*
3307 **  MILTER_ENVFROM -- send SMTP MAIL command info to milter filters
3308 **
3309 **      Parameters:
3310 **              args -- SMTP MAIL command args (args[0] == sender).
3311 **              e -- current envelope.
3312 **              state -- return state from response.
3313 **
3314 **      Returns:
3315 **              response string (may be NULL)
3316 */
3317
3318 char *
3319 milter_envfrom(args, e, state)
3320         char **args;
3321         ENVELOPE *e;
3322         char *state;
3323 {
3324         int i;
3325         char *buf, *bp;
3326         char *response;
3327         ssize_t s;
3328
3329         if (tTd(64, 10))
3330         {
3331                 sm_dprintf("milter_envfrom:");
3332                 for (i = 0; args[i] != NULL; i++)
3333                         sm_dprintf(" %s", args[i]);
3334                 sm_dprintf("\n");
3335         }
3336
3337         /* sanity check */
3338         if (args[0] == NULL)
3339         {
3340                 *state = SMFIR_REJECT;
3341                 if (MilterLogLevel > 10)
3342                         sm_syslog(LOG_INFO, e->e_id,
3343                                   "Milter: reject, no sender");
3344                 return NULL;
3345         }
3346
3347         /* new message, so ... */
3348         for (i = 0; InputFilters[i] != NULL; i++)
3349         {
3350                 struct milter *m = InputFilters[i];
3351
3352                 switch (m->mf_state)
3353                 {
3354                   case SMFS_INMSG:
3355                         /* abort in message filters */
3356                         milter_abort_filter(m, e);
3357                         /* FALLTHROUGH */
3358
3359                   case SMFS_DONE:
3360                         /* reset done filters */
3361                         m->mf_state = SMFS_OPEN;
3362                         break;
3363                 }
3364         }
3365
3366         /* put together data */
3367         s = 0;
3368         for (i = 0; args[i] != NULL; i++)
3369                 s += strlen(args[i]) + 1;
3370
3371         if (s < 0)
3372         {
3373                 *state = SMFIR_TEMPFAIL;
3374                 return NULL;
3375         }
3376
3377         buf = (char *) xalloc(s);
3378         bp = buf;
3379         for (i = 0; args[i] != NULL; i++)
3380         {
3381                 (void) sm_strlcpy(bp, args[i], s - (bp - buf));
3382                 bp += strlen(bp) + 1;
3383         }
3384
3385         if (MilterLogLevel > 14)
3386                 sm_syslog(LOG_INFO, e->e_id, "Milter: senders: %s", buf);
3387
3388         /* send it over */
3389         response = milter_command(SMFIC_MAIL, buf, s,
3390                                   MilterEnvFromMacros, e, state);
3391         sm_free(buf); /* XXX */
3392
3393         /*
3394         **  If filter rejects/discards a per message command,
3395         **  abort the other filters since we are done with the
3396         **  current message.
3397         */
3398
3399         MILTER_CHECK_DONE_MSG();
3400         if (MilterLogLevel > 10 && *state == SMFIR_REJECT)
3401                 sm_syslog(LOG_INFO, e->e_id, "Milter: reject, senders");
3402         return response;
3403 }
3404 /*
3405 **  MILTER_ENVRCPT -- send SMTP RCPT command info to milter filters
3406 **
3407 **      Parameters:
3408 **              args -- SMTP MAIL command args (args[0] == recipient).
3409 **              e -- current envelope.
3410 **              state -- return state from response.
3411 **
3412 **      Returns:
3413 **              response string (may be NULL)
3414 */
3415
3416 char *
3417 milter_envrcpt(args, e, state)
3418         char **args;
3419         ENVELOPE *e;
3420         char *state;
3421 {
3422         int i;
3423         char *buf, *bp;
3424         char *response;
3425         ssize_t s;
3426
3427         if (tTd(64, 10))
3428         {
3429                 sm_dprintf("milter_envrcpt:");
3430                 for (i = 0; args[i] != NULL; i++)
3431                         sm_dprintf(" %s", args[i]);
3432                 sm_dprintf("\n");
3433         }
3434
3435         /* sanity check */
3436         if (args[0] == NULL)
3437         {
3438                 *state = SMFIR_REJECT;
3439                 if (MilterLogLevel > 10)
3440                         sm_syslog(LOG_INFO, e->e_id, "Milter: reject, no rcpt");
3441                 return NULL;
3442         }
3443
3444         /* put together data */
3445         s = 0;
3446         for (i = 0; args[i] != NULL; i++)
3447                 s += strlen(args[i]) + 1;
3448
3449         if (s < 0)
3450         {
3451                 *state = SMFIR_TEMPFAIL;
3452                 return NULL;
3453         }
3454
3455         buf = (char *) xalloc(s);
3456         bp = buf;
3457         for (i = 0; args[i] != NULL; i++)
3458         {
3459                 (void) sm_strlcpy(bp, args[i], s - (bp - buf));
3460                 bp += strlen(bp) + 1;
3461         }
3462
3463         if (MilterLogLevel > 14)
3464                 sm_syslog(LOG_INFO, e->e_id, "Milter: rcpts: %s", buf);
3465
3466         /* send it over */
3467         response = milter_command(SMFIC_RCPT, buf, s,
3468                                   MilterEnvRcptMacros, e, state);
3469         sm_free(buf); /* XXX */
3470         return response;
3471 }
3472 /*
3473 **  MILTER_DATA -- send message headers/body and gather final message results
3474 **
3475 **      Parameters:
3476 **              e -- current envelope.
3477 **              state -- return state from response.
3478 **
3479 **      Returns:
3480 **              response string (may be NULL)
3481 **
3482 **      Side effects:
3483 **              - Uses e->e_dfp for access to the body
3484 **              - Can call the various milter action routines to
3485 **                modify the envelope or message.
3486 */
3487
3488 # define MILTER_CHECK_RESULTS() \
3489         if (*state == SMFIR_ACCEPT || \
3490             m->mf_state == SMFS_DONE || \
3491             m->mf_state == SMFS_ERROR) \
3492         { \
3493                 if (m->mf_state != SMFS_ERROR) \
3494                         m->mf_state = SMFS_DONE; \
3495                 continue;       /* to next filter */ \
3496         } \
3497         if (*state != SMFIR_CONTINUE) \
3498         { \
3499                 m->mf_state = SMFS_DONE; \
3500                 goto finishup; \
3501         }
3502
3503 char *
3504 milter_data(e, state)
3505         ENVELOPE *e;
3506         char *state;
3507 {
3508         bool replbody = false;          /* milter_replbody() called? */
3509         bool replfailed = false;        /* milter_replbody() failed? */
3510         bool rewind = false;            /* rewind data file? */
3511         bool dfopen = false;            /* data file open for writing? */
3512         bool newfilter;                 /* reset on each new filter */
3513         char rcmd;
3514         int i;
3515         int save_errno;
3516         char *response = NULL;
3517         time_t eomsent;
3518         ssize_t rlen;
3519
3520         if (tTd(64, 10))
3521                 sm_dprintf("milter_data\n");
3522
3523         *state = SMFIR_CONTINUE;
3524
3525         /*
3526         **  XXX: Should actually send body chunks to each filter
3527         **  a chunk at a time instead of sending the whole body to
3528         **  each filter in turn.  However, only if the filters don't
3529         **  change the body.
3530         */
3531
3532         for (i = 0; InputFilters[i] != NULL; i++)
3533         {
3534                 struct milter *m = InputFilters[i];
3535
3536                 if (*state != SMFIR_CONTINUE &&
3537                     *state != SMFIR_ACCEPT)
3538                 {
3539                         /*
3540                         **  A previous filter has dealt with the message,
3541                         **  safe to stop processing the filters.
3542                         */
3543
3544                         break;
3545                 }
3546
3547                 /* Now reset state for later evaluation */
3548                 *state = SMFIR_CONTINUE;
3549                 newfilter = true;
3550
3551                 /* previous problem? */
3552                 if (m->mf_state == SMFS_ERROR)
3553                 {
3554                         MILTER_CHECK_ERROR(false, continue);
3555                         break;
3556                 }
3557
3558                 /* sanity checks */
3559                 if (m->mf_sock < 0 ||
3560                     (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG))
3561                         continue;
3562
3563                 m->mf_state = SMFS_INMSG;
3564
3565                 /* check if filter wants the headers */
3566                 if (!bitset(SMFIP_NOHDRS, m->mf_pflags))
3567                 {
3568                         response = milter_headers(m, e, state);
3569                         MILTER_CHECK_RESULTS();
3570                 }
3571
3572                 /* check if filter wants EOH */
3573                 if (!bitset(SMFIP_NOEOH, m->mf_pflags))
3574                 {
3575                         if (tTd(64, 10))
3576                                 sm_dprintf("milter_data: eoh\n");
3577
3578                         /* send it over */
3579                         response = milter_send_command(m, SMFIC_EOH, NULL, 0,
3580                                                        e, state);
3581                         MILTER_CHECK_RESULTS();
3582                 }
3583
3584                 /* check if filter wants the body */
3585                 if (!bitset(SMFIP_NOBODY, m->mf_pflags) &&
3586                     e->e_dfp != NULL)
3587                 {
3588                         rewind = true;
3589                         response = milter_body(m, e, state);
3590                         MILTER_CHECK_RESULTS();
3591                 }
3592
3593                 /* send the final body chunk */
3594                 (void) milter_write(m, SMFIC_BODYEOB, NULL, 0,
3595                                     m->mf_timeout[SMFTO_WRITE], e);
3596
3597                 /* Get time EOM sent for timeout */
3598                 eomsent = curtime();
3599
3600                 /* deal with the possibility of multiple responses */
3601                 while (*state == SMFIR_CONTINUE)
3602                 {
3603                         /* Check total timeout from EOM to final ACK/NAK */
3604                         if (m->mf_timeout[SMFTO_EOM] > 0 &&
3605                             curtime() - eomsent >= m->mf_timeout[SMFTO_EOM])
3606                         {
3607                                 if (tTd(64, 5))
3608                                         sm_dprintf("milter_data(%s): EOM ACK/NAK timeout\n",
3609                                                 m->mf_name);
3610                                 if (MilterLogLevel > 0)
3611                                         sm_syslog(LOG_ERR, e->e_id,
3612                                                   "milter_data(%s): EOM ACK/NAK timeout",
3613                                                   m->mf_name);
3614                                 milter_error(m, e);
3615                                 MILTER_CHECK_ERROR(false, break);
3616                                 break;
3617                         }
3618
3619                         response = milter_read(m, &rcmd, &rlen,
3620                                                m->mf_timeout[SMFTO_READ], e);
3621                         if (m->mf_state == SMFS_ERROR)
3622                                 break;
3623
3624                         if (tTd(64, 10))
3625                                 sm_dprintf("milter_data(%s): state %c\n",
3626                                            m->mf_name, (char) rcmd);
3627
3628                         switch (rcmd)
3629                         {
3630                           case SMFIR_REPLYCODE:
3631                                 MILTER_CHECK_REPLYCODE("554 5.7.1 Command rejected");
3632                                 if (MilterLogLevel > 12)
3633                                         sm_syslog(LOG_INFO, e->e_id, "milter=%s, reject=%s",
3634                                                   m->mf_name, response);
3635                                 *state = rcmd;
3636                                 m->mf_state = SMFS_DONE;
3637                                 break;
3638
3639                           case SMFIR_REJECT: /* log msg at end of function */
3640                                 if (MilterLogLevel > 12)
3641                                         sm_syslog(LOG_INFO, e->e_id, "milter=%s, reject",
3642                                                   m->mf_name);
3643                                 *state = rcmd;
3644                                 m->mf_state = SMFS_DONE;
3645                                 break;
3646
3647                           case SMFIR_DISCARD:
3648                                 if (MilterLogLevel > 12)
3649                                         sm_syslog(LOG_INFO, e->e_id, "milter=%s, discard",
3650                                                   m->mf_name);
3651                                 *state = rcmd;
3652                                 m->mf_state = SMFS_DONE;
3653                                 break;
3654
3655                           case SMFIR_TEMPFAIL:
3656                                 if (MilterLogLevel > 12)
3657                                         sm_syslog(LOG_INFO, e->e_id, "milter=%s, tempfail",
3658                                                   m->mf_name);
3659                                 *state = rcmd;
3660                                 m->mf_state = SMFS_DONE;
3661                                 break;
3662
3663                           case SMFIR_CONTINUE:
3664                           case SMFIR_ACCEPT:
3665                                 /* this filter is done with message */
3666                                 if (replfailed)
3667                                         *state = SMFIR_TEMPFAIL;
3668                                 else
3669                                         *state = SMFIR_ACCEPT;
3670                                 m->mf_state = SMFS_DONE;
3671                                 break;
3672
3673                           case SMFIR_PROGRESS:
3674                                 break;
3675
3676 # if _FFR_QUARANTINE
3677                           case SMFIR_QUARANTINE:
3678                                 if (!bitset(SMFIF_QUARANTINE, m->mf_fflags))
3679                                 {
3680                                         if (MilterLogLevel > 9)
3681                                                 sm_syslog(LOG_WARNING, e->e_id,
3682                                                           "milter_data(%s): lied about quarantining, honoring request anyway",
3683                                                           m->mf_name);
3684                                 }
3685                                 if (response == NULL)
3686                                         response = newstr("");
3687                                 if (MilterLogLevel > 3)
3688                                         sm_syslog(LOG_INFO, e->e_id,
3689                                                   "milter=%s, quarantine=%s",
3690                                                   m->mf_name, response);
3691                                 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool,
3692                                                                  response);
3693                                 macdefine(&e->e_macro, A_PERM,
3694                                           macid("{quarantine}"), e->e_quarmsg);
3695                                 break;
3696 # endif /* _FFR_QUARANTINE */
3697
3698                           case SMFIR_ADDHEADER:
3699                                 if (!bitset(SMFIF_ADDHDRS, m->mf_fflags))
3700                                 {
3701                                         if (MilterLogLevel > 9)
3702                                                 sm_syslog(LOG_WARNING, e->e_id,
3703                                                           "milter_data(%s): lied about adding headers, honoring request anyway",
3704                                                           m->mf_name);
3705                                 }
3706                                 milter_addheader(response, rlen, e);
3707                                 break;
3708
3709                           case SMFIR_CHGHEADER:
3710                                 if (!bitset(SMFIF_CHGHDRS, m->mf_fflags))
3711                                 {
3712                                         if (MilterLogLevel > 9)
3713                                                 sm_syslog(LOG_WARNING, e->e_id,
3714                                                           "milter_data(%s): lied about changing headers, honoring request anyway",
3715                                                           m->mf_name);
3716                                 }
3717                                 milter_changeheader(response, rlen, e);
3718                                 break;
3719
3720                           case SMFIR_ADDRCPT:
3721                                 if (!bitset(SMFIF_ADDRCPT, m->mf_fflags))
3722                                 {
3723                                         if (MilterLogLevel > 9)
3724                                                 sm_syslog(LOG_WARNING, e->e_id,
3725                                                           "milter_data(%s) lied about adding recipients, honoring request anyway",
3726                                                           m->mf_name);
3727                                 }
3728                                 milter_addrcpt(response, rlen, e);
3729                                 break;
3730
3731                           case SMFIR_DELRCPT:
3732                                 if (!bitset(SMFIF_DELRCPT, m->mf_fflags))
3733                                 {
3734                                         if (MilterLogLevel > 9)
3735                                                 sm_syslog(LOG_WARNING, e->e_id,
3736                                                           "milter_data(%s): lied about removing recipients, honoring request anyway",
3737                                                           m->mf_name);
3738                                 }
3739                                 milter_delrcpt(response, rlen, e);
3740                                 break;
3741
3742                           case SMFIR_REPLBODY:
3743                                 if (!bitset(SMFIF_MODBODY, m->mf_fflags))
3744                                 {
3745                                         if (MilterLogLevel > 9)
3746                                                 sm_syslog(LOG_ERR, e->e_id,
3747                                                           "milter_data(%s): lied about replacing body, rejecting request and tempfailing message",
3748                                                           m->mf_name);
3749                                         replfailed = true;
3750                                         break;
3751                                 }
3752
3753                                 /* already failed in attempt */
3754                                 if (replfailed)
3755                                         break;
3756
3757                                 if (!dfopen)
3758                                 {
3759                                         if (milter_reopen_df(e) < 0)
3760                                         {
3761                                                 replfailed = true;
3762                                                 break;
3763                                         }
3764                                         dfopen = true;
3765                                         rewind = true;
3766                                 }
3767
3768                                 if (milter_replbody(response, rlen,
3769                                                     newfilter, e) < 0)
3770                                         replfailed = true;
3771                                 newfilter = false;
3772                                 replbody = true;
3773                                 break;
3774
3775                           default:
3776                                 /* Invalid response to command */
3777                                 if (MilterLogLevel > 0)
3778                                         sm_syslog(LOG_ERR, e->e_id,
3779                                                   "milter_data(%s): returned bogus response %c",
3780                                                   m->mf_name, rcmd);
3781                                 milter_error(m, e);
3782                                 break;
3783                         }
3784                         if (rcmd != SMFIR_REPLYCODE && response != NULL)
3785                         {
3786                                 sm_free(response); /* XXX */
3787                                 response = NULL;
3788                         }
3789
3790                         if (m->mf_state == SMFS_ERROR)
3791                                 break;
3792                 }
3793
3794                 if (replbody && !replfailed)
3795                 {
3796                         /* flush possible buffered character */
3797                         milter_replbody(NULL, 0, !replbody, e);
3798                         replbody = false;
3799                 }
3800
3801                 if (m->mf_state == SMFS_ERROR)
3802                 {
3803                         MILTER_CHECK_ERROR(false, continue);
3804                         goto finishup;
3805                 }
3806         }
3807
3808 finishup:
3809         /* leave things in the expected state if we touched it */
3810         if (replfailed)
3811         {
3812                 if (*state == SMFIR_CONTINUE ||
3813                     *state == SMFIR_ACCEPT)
3814                 {
3815                         *state = SMFIR_TEMPFAIL;
3816                         SM_FREE_CLR(response);
3817                 }
3818
3819                 if (dfopen)
3820                 {
3821                         (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT);
3822                         e->e_dfp = NULL;
3823                         e->e_flags &= ~EF_HAS_DF;
3824                         dfopen = false;
3825                 }
3826                 rewind = false;
3827         }
3828
3829         if ((dfopen && milter_reset_df(e) < 0) ||
3830             (rewind && bfrewind(e->e_dfp) < 0))
3831         {
3832                 save_errno = errno;
3833                 ExitStat = EX_IOERR;
3834
3835                 /*
3836                 **  If filter told us to keep message but we had
3837                 **  an error, we can't really keep it, tempfail it.
3838                 */
3839
3840                 if (*state == SMFIR_CONTINUE ||
3841                     *state == SMFIR_ACCEPT)
3842                 {
3843                         *state = SMFIR_TEMPFAIL;
3844                         SM_FREE_CLR(response);
3845                 }
3846
3847                 errno = save_errno;
3848                 syserr("milter_data: %s/%cf%s: read error",
3849                        qid_printqueue(e->e_qgrp, e->e_qdir),
3850                        DATAFL_LETTER, e->e_id);
3851         }
3852
3853         MILTER_CHECK_DONE_MSG();
3854         if (MilterLogLevel > 10 && *state == SMFIR_REJECT)
3855                 sm_syslog(LOG_INFO, e->e_id, "Milter: reject, data");
3856         return response;
3857 }
3858 /*
3859 **  MILTER_QUIT -- informs the filter(s) we are done and closes connection(s)
3860 **
3861 **      Parameters:
3862 **              e -- current envelope.
3863 **
3864 **      Returns:
3865 **              none
3866 */
3867
3868 void
3869 milter_quit(e)
3870         ENVELOPE *e;
3871 {
3872         int i;
3873
3874         if (tTd(64, 10))
3875                 sm_dprintf("milter_quit(%s)\n", e->e_id);
3876
3877         for (i = 0; InputFilters[i] != NULL; i++)
3878                 milter_quit_filter(InputFilters[i], e);
3879 }
3880 /*
3881 **  MILTER_ABORT -- informs the filter(s) that we are aborting current message
3882 **
3883 **      Parameters:
3884 **              e -- current envelope.
3885 **
3886 **      Returns:
3887 **              none
3888 */
3889
3890 void
3891 milter_abort(e)
3892         ENVELOPE *e;
3893 {
3894         int i;
3895
3896         if (tTd(64, 10))
3897                 sm_dprintf("milter_abort\n");
3898
3899         for (i = 0; InputFilters[i] != NULL; i++)
3900         {
3901                 struct milter *m = InputFilters[i];
3902
3903                 /* sanity checks */
3904                 if (m->mf_sock < 0 || m->mf_state != SMFS_INMSG)
3905                         continue;
3906
3907                 milter_abort_filter(m, e);
3908         }
3909 }
3910 #endif /* MILTER */