Merge from vendor branch LIBSTDC++:
[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.9 2003/09/07 00:18:29 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_B, 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_B, 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         int olderrors;
2811
2812         if (tTd(64, 10))
2813                 sm_dprintf("milter_addrcpt: ");
2814
2815         /* sanity checks */
2816         if (response == NULL)
2817         {
2818                 if (tTd(64, 10))
2819                         sm_dprintf("NULL response\n");
2820                 return;
2821         }
2822
2823         if (*response == '\0' ||
2824             strlen(response) + 1 != (size_t) rlen)
2825         {
2826                 if (tTd(64, 10))
2827                         sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n",
2828                                    (int) strlen(response), (int) (rlen - 1));
2829                 return;
2830         }
2831
2832         if (tTd(64, 10))
2833                 sm_dprintf("%s\n", response);
2834         if (MilterLogLevel > 8)
2835                 sm_syslog(LOG_INFO, e->e_id, "Milter add: rcpt: %s", response);
2836         olderrors = Errors;
2837         (void) sendtolist(response, NULLADDR, &e->e_sendqueue, 0, e);
2838         Errors = olderrors;
2839         return;
2840 }
2841 /*
2842 **  MILTER_DELRCPT -- Delete the supplied recipient from the message
2843 **
2844 **      Parameters:
2845 **              response -- encoded form of recipient address.
2846 **              rlen -- length of response.
2847 **              e -- current envelope.
2848 **
2849 **      Returns:
2850 **              none
2851 */
2852
2853 static void
2854 milter_delrcpt(response, rlen, e)
2855         char *response;
2856         ssize_t rlen;
2857         ENVELOPE *e;
2858 {
2859         if (tTd(64, 10))
2860                 sm_dprintf("milter_delrcpt: ");
2861
2862         /* sanity checks */
2863         if (response == NULL)
2864         {
2865                 if (tTd(64, 10))
2866                         sm_dprintf("NULL response\n");
2867                 return;
2868         }
2869
2870         if (*response == '\0' ||
2871             strlen(response) + 1 != (size_t) rlen)
2872         {
2873                 if (tTd(64, 10))
2874                         sm_dprintf("didn't follow protocol (total len)\n");
2875                 return;
2876         }
2877
2878         if (tTd(64, 10))
2879                 sm_dprintf("%s\n", response);
2880         if (MilterLogLevel > 8)
2881                 sm_syslog(LOG_INFO, e->e_id, "Milter delete: rcpt %s",
2882                           response);
2883         (void) removefromlist(response, &e->e_sendqueue, e);
2884         return;
2885 }
2886 /*
2887 **  MILTER_REPLBODY -- Replace the current data file with new body
2888 **
2889 **      Parameters:
2890 **              response -- encoded form of new body.
2891 **              rlen -- length of response.
2892 **              newfilter -- if first time called by a new filter
2893 **              e -- current envelope.
2894 **
2895 **      Returns:
2896 **              0 upon success, -1 upon failure
2897 */
2898
2899 static int
2900 milter_replbody(response, rlen, newfilter, e)
2901         char *response;
2902         ssize_t rlen;
2903         bool newfilter;
2904         ENVELOPE *e;
2905 {
2906         static char prevchar;
2907         int i;
2908
2909         if (tTd(64, 10))
2910                 sm_dprintf("milter_replbody\n");
2911
2912         /* If a new filter, reset previous character and truncate data file */
2913         if (newfilter)
2914         {
2915                 off_t prevsize;
2916                 char dfname[MAXPATHLEN];
2917
2918                 (void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER),
2919                                   sizeof dfname);
2920
2921                 /* Reset prevchar */
2922                 prevchar = '\0';
2923
2924                 /* Get the current data file information */
2925                 prevsize = sm_io_getinfo(e->e_dfp, SM_IO_WHAT_SIZE, NULL);
2926                 if (prevsize < 0)
2927                         prevsize = 0;
2928
2929                 /* truncate current data file */
2930                 if (sm_io_getinfo(e->e_dfp, SM_IO_WHAT_ISTYPE, BF_FILE_TYPE))
2931                 {
2932                         if (sm_io_setinfo(e->e_dfp, SM_BF_TRUNCATE, NULL) < 0)
2933                         {
2934                                 MILTER_DF_ERROR("milter_replbody: sm_io truncate %s: %s");
2935                                 return -1;
2936                         }
2937                 }
2938                 else
2939                 {
2940                         int err;
2941
2942                         err = sm_io_error(e->e_dfp);
2943                         (void) sm_io_flush(e->e_dfp, SM_TIME_DEFAULT);
2944
2945                         /*
2946                         **  Clear error if tried to fflush()
2947                         **  a read-only file pointer and
2948                         **  there wasn't a previous error.
2949                         */
2950
2951                         if (err == 0)
2952                                 sm_io_clearerr(e->e_dfp);
2953
2954                         /* errno is set implicitly by fseek() before return */
2955                         err = sm_io_seek(e->e_dfp, SM_TIME_DEFAULT,
2956                                          0, SEEK_SET);
2957                         if (err < 0)
2958                         {
2959                                 MILTER_DF_ERROR("milter_replbody: sm_io_seek %s: %s");
2960                                 return -1;
2961                         }
2962 # if NOFTRUNCATE
2963                         /* XXX: Not much we can do except rewind it */
2964                         errno = EINVAL;
2965                         MILTER_DF_ERROR("milter_replbody: ftruncate not available on this platform (%s:%s)");
2966                         return -1;
2967 # else /* NOFTRUNCATE */
2968                         err = ftruncate(sm_io_getinfo(e->e_dfp,
2969                                                       SM_IO_WHAT_FD, NULL),
2970                                         0);
2971                         if (err < 0)
2972                         {
2973                                 MILTER_DF_ERROR("milter_replbody: sm_io ftruncate %s: %s");
2974                                 return -1;
2975                         }
2976 # endif /* NOFTRUNCATE */
2977                 }
2978
2979                 if (prevsize > e->e_msgsize)
2980                         e->e_msgsize = 0;
2981                 else
2982                         e->e_msgsize -= prevsize;
2983         }
2984
2985         if (newfilter && MilterLogLevel > 8)
2986                 sm_syslog(LOG_INFO, e->e_id, "Milter message: body replaced");
2987
2988         if (response == NULL)
2989         {
2990                 /* Flush the buffered '\r' */
2991                 if (prevchar == '\r')
2992                 {
2993                         (void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT, prevchar);
2994                         e->e_msgsize++;
2995                 }
2996                 return 0;
2997         }
2998
2999         for (i = 0; i < rlen; i++)
3000         {
3001                 /* Buffered char from last chunk */
3002                 if (i == 0 && prevchar == '\r')
3003                 {
3004                         /* Not CRLF, output prevchar */
3005                         if (response[i] != '\n')
3006                         {
3007                                 (void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT,
3008                                                   prevchar);
3009                                 e->e_msgsize++;
3010                         }
3011                         prevchar = '\0';
3012                 }
3013
3014                 /* Turn CRLF into LF */
3015                 if (response[i] == '\r')
3016                 {
3017                         /* check if at end of chunk */
3018                         if (i + 1 < rlen)
3019                         {
3020                                 /* If LF, strip CR */
3021                                 if (response[i + 1] == '\n')
3022                                         i++;
3023                         }
3024                         else
3025                         {
3026                                 /* check next chunk */
3027                                 prevchar = '\r';
3028                                 continue;
3029                         }
3030                 }
3031                 (void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT, response[i]);
3032                 e->e_msgsize++;
3033         }
3034         return 0;
3035 }
3036
3037 /*
3038 **  MTA callouts
3039 */
3040
3041 /*
3042 **  MILTER_INIT -- open and negotiate with all of the filters
3043 **
3044 **      Parameters:
3045 **              e -- current envelope.
3046 **              state -- return state from response.
3047 **
3048 **      Returns:
3049 **              true iff at least one filter is active
3050 */
3051
3052 /* ARGSUSED */
3053 bool
3054 milter_init(e, state)
3055         ENVELOPE *e;
3056         char *state;
3057 {
3058         int i;
3059
3060         if (tTd(64, 10))
3061                 sm_dprintf("milter_init\n");
3062
3063         *state = SMFIR_CONTINUE;
3064         if (InputFilters[0] == NULL)
3065         {
3066                 if (MilterLogLevel > 10)
3067                         sm_syslog(LOG_INFO, e->e_id,
3068                                   "Milter: no active filter");
3069                 return false;
3070         }
3071
3072         for (i = 0; InputFilters[i] != NULL; i++)
3073         {
3074                 struct milter *m = InputFilters[i];
3075
3076                 m->mf_sock = milter_open(m, false, e);
3077                 if (m->mf_state == SMFS_ERROR)
3078                 {
3079                         MILTER_CHECK_ERROR(true, continue);
3080                         break;
3081                 }
3082
3083                 if (m->mf_sock < 0 ||
3084                     milter_negotiate(m, e) < 0 ||
3085                     m->mf_state == SMFS_ERROR)
3086                 {
3087                         if (tTd(64, 5))
3088                                 sm_dprintf("milter_init(%s): failed to %s\n",
3089                                            m->mf_name,
3090                                            m->mf_sock < 0 ? "open" :
3091                                                             "negotiate");
3092                         if (MilterLogLevel > 0)
3093                                 sm_syslog(LOG_ERR, e->e_id,
3094                                           "Milter (%s): init failed to %s",
3095                                           m->mf_name,
3096                                           m->mf_sock < 0 ? "open" :
3097                                                            "negotiate");
3098
3099                         /* if negotation failure, close socket */
3100                         milter_error(m, e);
3101                         MILTER_CHECK_ERROR(true, continue);
3102                 }
3103                 if (MilterLogLevel > 9)
3104                         sm_syslog(LOG_INFO, e->e_id,
3105                                   "Milter (%s): init success to %s",
3106                                   m->mf_name,
3107                                   m->mf_sock < 0 ? "open" : "negotiate");
3108         }
3109
3110         /*
3111         **  If something temp/perm failed with one of the filters,
3112         **  we won't be using any of them, so clear any existing
3113         **  connections.
3114         */
3115
3116         if (*state != SMFIR_CONTINUE)
3117                 milter_quit(e);
3118
3119         return true;
3120 }
3121 /*
3122 **  MILTER_CONNECT -- send connection info to milter filters
3123 **
3124 **      Parameters:
3125 **              hostname -- hostname of remote machine.
3126 **              addr -- address of remote machine.
3127 **              e -- current envelope.
3128 **              state -- return state from response.
3129 **
3130 **      Returns:
3131 **              response string (may be NULL)
3132 */
3133
3134 char *
3135 milter_connect(hostname, addr, e, state)
3136         char *hostname;
3137         SOCKADDR addr;
3138         ENVELOPE *e;
3139         char *state;
3140 {
3141         char family;
3142         unsigned short port;
3143         char *buf, *bp;
3144         char *response;
3145         char *sockinfo = NULL;
3146         ssize_t s;
3147 # if NETINET6
3148         char buf6[INET6_ADDRSTRLEN];
3149 # endif /* NETINET6 */
3150
3151         if (tTd(64, 10))
3152                 sm_dprintf("milter_connect(%s)\n", hostname);
3153         if (MilterLogLevel > 9)
3154                 sm_syslog(LOG_INFO, e->e_id, "Milter: connect to filters");
3155
3156         /* gather data */
3157         switch (addr.sa.sa_family)
3158         {
3159 # if NETUNIX
3160           case AF_UNIX:
3161                 family = SMFIA_UNIX;
3162                 port = htons(0);
3163                 sockinfo = addr.sunix.sun_path;
3164                 break;
3165 # endif /* NETUNIX */
3166
3167 # if NETINET
3168           case AF_INET:
3169                 family = SMFIA_INET;
3170                 port = addr.sin.sin_port;
3171                 sockinfo = (char *) inet_ntoa(addr.sin.sin_addr);
3172                 break;
3173 # endif /* NETINET */
3174
3175 # if NETINET6
3176           case AF_INET6:
3177                 if (IN6_IS_ADDR_V4MAPPED(&addr.sin6.sin6_addr))
3178                         family = SMFIA_INET;
3179                 else
3180                         family = SMFIA_INET6;
3181                 port = addr.sin6.sin6_port;
3182                 sockinfo = anynet_ntop(&addr.sin6.sin6_addr, buf6,
3183                                        sizeof buf6);
3184                 if (sockinfo == NULL)
3185                         sockinfo = "";
3186                 break;
3187 # endif /* NETINET6 */
3188
3189           default:
3190                 family = SMFIA_UNKNOWN;
3191                 break;
3192         }
3193
3194         s = strlen(hostname) + 1 + sizeof(family);
3195         if (family != SMFIA_UNKNOWN)
3196                 s += sizeof(port) + strlen(sockinfo) + 1;
3197
3198         buf = (char *) xalloc(s);
3199         bp = buf;
3200
3201         /* put together data */
3202         (void) memcpy(bp, hostname, strlen(hostname));
3203         bp += strlen(hostname);
3204         *bp++ = '\0';
3205         (void) memcpy(bp, &family, sizeof family);
3206         bp += sizeof family;
3207         if (family != SMFIA_UNKNOWN)
3208         {
3209                 (void) memcpy(bp, &port, sizeof port);
3210                 bp += sizeof port;
3211
3212                 /* include trailing '\0' */
3213                 (void) memcpy(bp, sockinfo, strlen(sockinfo) + 1);
3214         }
3215
3216         response = milter_command(SMFIC_CONNECT, buf, s,
3217                                   MilterConnectMacros, e, state);
3218         sm_free(buf); /* XXX */
3219
3220         /*
3221         **  If this message connection is done for,
3222         **  close the filters.
3223         */
3224
3225         if (*state != SMFIR_CONTINUE)
3226         {
3227                 if (MilterLogLevel > 9)
3228                         sm_syslog(LOG_INFO, e->e_id, "Milter: connect, ending");
3229                 milter_quit(e);
3230         }
3231         else
3232                 milter_per_connection_check(e);
3233
3234         /*
3235         **  SMFIR_REPLYCODE can't work with connect due to
3236         **  the requirements of SMTP.  Therefore, ignore the
3237         **  reply code text but keep the state it would reflect.
3238         */
3239
3240         if (*state == SMFIR_REPLYCODE)
3241         {
3242                 if (response != NULL &&
3243                     *response == '4')
3244                 {
3245 #if _FFR_MILTER_421
3246                         if (strncmp(response, "421 ", 4) == 0)
3247                                 *state = SMFIR_SHUTDOWN;
3248                         else
3249 #endif /* _FFR_MILTER_421 */
3250                                 *state = SMFIR_TEMPFAIL;
3251                 }
3252                 else
3253                         *state = SMFIR_REJECT;
3254                 if (response != NULL)
3255                 {
3256                         sm_free(response); /* XXX */
3257                         response = NULL;
3258                 }
3259         }
3260         return response;
3261 }
3262 /*
3263 **  MILTER_HELO -- send SMTP HELO/EHLO command info to milter filters
3264 **
3265 **      Parameters:
3266 **              helo -- argument to SMTP HELO/EHLO command.
3267 **              e -- current envelope.
3268 **              state -- return state from response.
3269 **
3270 **      Returns:
3271 **              response string (may be NULL)
3272 */
3273
3274 char *
3275 milter_helo(helo, e, state)
3276         char *helo;
3277         ENVELOPE *e;
3278         char *state;
3279 {
3280         int i;
3281         char *response;
3282
3283         if (tTd(64, 10))
3284                 sm_dprintf("milter_helo(%s)\n", helo);
3285
3286         /* HELO/EHLO can come at any point */
3287         for (i = 0; InputFilters[i] != NULL; i++)
3288         {
3289                 struct milter *m = InputFilters[i];
3290
3291                 switch (m->mf_state)
3292                 {
3293                   case SMFS_INMSG:
3294                         /* abort in message filters */
3295                         milter_abort_filter(m, e);
3296                         /* FALLTHROUGH */
3297
3298                   case SMFS_DONE:
3299                         /* reset done filters */
3300                         m->mf_state = SMFS_OPEN;
3301                         break;
3302                 }
3303         }
3304
3305         response = milter_command(SMFIC_HELO, helo, strlen(helo) + 1,
3306                                   MilterHeloMacros, e, state);
3307         milter_per_connection_check(e);
3308         return response;
3309 }
3310 /*
3311 **  MILTER_ENVFROM -- send SMTP MAIL command info to milter filters
3312 **
3313 **      Parameters:
3314 **              args -- SMTP MAIL command args (args[0] == sender).
3315 **              e -- current envelope.
3316 **              state -- return state from response.
3317 **
3318 **      Returns:
3319 **              response string (may be NULL)
3320 */
3321
3322 char *
3323 milter_envfrom(args, e, state)
3324         char **args;
3325         ENVELOPE *e;
3326         char *state;
3327 {
3328         int i;
3329         char *buf, *bp;
3330         char *response;
3331         ssize_t s;
3332
3333         if (tTd(64, 10))
3334         {
3335                 sm_dprintf("milter_envfrom:");
3336                 for (i = 0; args[i] != NULL; i++)
3337                         sm_dprintf(" %s", args[i]);
3338                 sm_dprintf("\n");
3339         }
3340
3341         /* sanity check */
3342         if (args[0] == NULL)
3343         {
3344                 *state = SMFIR_REJECT;
3345                 if (MilterLogLevel > 10)
3346                         sm_syslog(LOG_INFO, e->e_id,
3347                                   "Milter: reject, no sender");
3348                 return NULL;
3349         }
3350
3351         /* new message, so ... */
3352         for (i = 0; InputFilters[i] != NULL; i++)
3353         {
3354                 struct milter *m = InputFilters[i];
3355
3356                 switch (m->mf_state)
3357                 {
3358                   case SMFS_INMSG:
3359                         /* abort in message filters */
3360                         milter_abort_filter(m, e);
3361                         /* FALLTHROUGH */
3362
3363                   case SMFS_DONE:
3364                         /* reset done filters */
3365                         m->mf_state = SMFS_OPEN;
3366                         break;
3367                 }
3368         }
3369
3370         /* put together data */
3371         s = 0;
3372         for (i = 0; args[i] != NULL; i++)
3373                 s += strlen(args[i]) + 1;
3374
3375         if (s < 0)
3376         {
3377                 *state = SMFIR_TEMPFAIL;
3378                 return NULL;
3379         }
3380
3381         buf = (char *) xalloc(s);
3382         bp = buf;
3383         for (i = 0; args[i] != NULL; i++)
3384         {
3385                 (void) sm_strlcpy(bp, args[i], s - (bp - buf));
3386                 bp += strlen(bp) + 1;
3387         }
3388
3389         if (MilterLogLevel > 14)
3390                 sm_syslog(LOG_INFO, e->e_id, "Milter: senders: %s", buf);
3391
3392         /* send it over */
3393         response = milter_command(SMFIC_MAIL, buf, s,
3394                                   MilterEnvFromMacros, e, state);
3395         sm_free(buf); /* XXX */
3396
3397         /*
3398         **  If filter rejects/discards a per message command,
3399         **  abort the other filters since we are done with the
3400         **  current message.
3401         */
3402
3403         MILTER_CHECK_DONE_MSG();
3404         if (MilterLogLevel > 10 && *state == SMFIR_REJECT)
3405                 sm_syslog(LOG_INFO, e->e_id, "Milter: reject, senders");
3406         return response;
3407 }
3408 /*
3409 **  MILTER_ENVRCPT -- send SMTP RCPT command info to milter filters
3410 **
3411 **      Parameters:
3412 **              args -- SMTP MAIL command args (args[0] == recipient).
3413 **              e -- current envelope.
3414 **              state -- return state from response.
3415 **
3416 **      Returns:
3417 **              response string (may be NULL)
3418 */
3419
3420 char *
3421 milter_envrcpt(args, e, state)
3422         char **args;
3423         ENVELOPE *e;
3424         char *state;
3425 {
3426         int i;
3427         char *buf, *bp;
3428         char *response;
3429         ssize_t s;
3430
3431         if (tTd(64, 10))
3432         {
3433                 sm_dprintf("milter_envrcpt:");
3434                 for (i = 0; args[i] != NULL; i++)
3435                         sm_dprintf(" %s", args[i]);
3436                 sm_dprintf("\n");
3437         }
3438
3439         /* sanity check */
3440         if (args[0] == NULL)
3441         {
3442                 *state = SMFIR_REJECT;
3443                 if (MilterLogLevel > 10)
3444                         sm_syslog(LOG_INFO, e->e_id, "Milter: reject, no rcpt");
3445                 return NULL;
3446         }
3447
3448         /* put together data */
3449         s = 0;
3450         for (i = 0; args[i] != NULL; i++)
3451                 s += strlen(args[i]) + 1;
3452
3453         if (s < 0)
3454         {
3455                 *state = SMFIR_TEMPFAIL;
3456                 return NULL;
3457         }
3458
3459         buf = (char *) xalloc(s);
3460         bp = buf;
3461         for (i = 0; args[i] != NULL; i++)
3462         {
3463                 (void) sm_strlcpy(bp, args[i], s - (bp - buf));
3464                 bp += strlen(bp) + 1;
3465         }
3466
3467         if (MilterLogLevel > 14)
3468                 sm_syslog(LOG_INFO, e->e_id, "Milter: rcpts: %s", buf);
3469
3470         /* send it over */
3471         response = milter_command(SMFIC_RCPT, buf, s,
3472                                   MilterEnvRcptMacros, e, state);
3473         sm_free(buf); /* XXX */
3474         return response;
3475 }
3476 /*
3477 **  MILTER_DATA -- send message headers/body and gather final message results
3478 **
3479 **      Parameters:
3480 **              e -- current envelope.
3481 **              state -- return state from response.
3482 **
3483 **      Returns:
3484 **              response string (may be NULL)
3485 **
3486 **      Side effects:
3487 **              - Uses e->e_dfp for access to the body
3488 **              - Can call the various milter action routines to
3489 **                modify the envelope or message.
3490 */
3491
3492 # define MILTER_CHECK_RESULTS() \
3493         if (*state == SMFIR_ACCEPT || \
3494             m->mf_state == SMFS_DONE || \
3495             m->mf_state == SMFS_ERROR) \
3496         { \
3497                 if (m->mf_state != SMFS_ERROR) \
3498                         m->mf_state = SMFS_DONE; \
3499                 continue;       /* to next filter */ \
3500         } \
3501         if (*state != SMFIR_CONTINUE) \
3502         { \
3503                 m->mf_state = SMFS_DONE; \
3504                 goto finishup; \
3505         }
3506
3507 char *
3508 milter_data(e, state)
3509         ENVELOPE *e;
3510         char *state;
3511 {
3512         bool replbody = false;          /* milter_replbody() called? */
3513         bool replfailed = false;        /* milter_replbody() failed? */
3514         bool rewind = false;            /* rewind data file? */
3515         bool dfopen = false;            /* data file open for writing? */
3516         bool newfilter;                 /* reset on each new filter */
3517         char rcmd;
3518         int i;
3519         int save_errno;
3520         char *response = NULL;
3521         time_t eomsent;
3522         ssize_t rlen;
3523
3524         if (tTd(64, 10))
3525                 sm_dprintf("milter_data\n");
3526
3527         *state = SMFIR_CONTINUE;
3528
3529         /*
3530         **  XXX: Should actually send body chunks to each filter
3531         **  a chunk at a time instead of sending the whole body to
3532         **  each filter in turn.  However, only if the filters don't
3533         **  change the body.
3534         */
3535
3536         for (i = 0; InputFilters[i] != NULL; i++)
3537         {
3538                 struct milter *m = InputFilters[i];
3539
3540                 if (*state != SMFIR_CONTINUE &&
3541                     *state != SMFIR_ACCEPT)
3542                 {
3543                         /*
3544                         **  A previous filter has dealt with the message,
3545                         **  safe to stop processing the filters.
3546                         */
3547
3548                         break;
3549                 }
3550
3551                 /* Now reset state for later evaluation */
3552                 *state = SMFIR_CONTINUE;
3553                 newfilter = true;
3554
3555                 /* previous problem? */
3556                 if (m->mf_state == SMFS_ERROR)
3557                 {
3558                         MILTER_CHECK_ERROR(false, continue);
3559                         break;
3560                 }
3561
3562                 /* sanity checks */
3563                 if (m->mf_sock < 0 ||
3564                     (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG))
3565                         continue;
3566
3567                 m->mf_state = SMFS_INMSG;
3568
3569                 /* check if filter wants the headers */
3570                 if (!bitset(SMFIP_NOHDRS, m->mf_pflags))
3571                 {
3572                         response = milter_headers(m, e, state);
3573                         MILTER_CHECK_RESULTS();
3574                 }
3575
3576                 /* check if filter wants EOH */
3577                 if (!bitset(SMFIP_NOEOH, m->mf_pflags))
3578                 {
3579                         if (tTd(64, 10))
3580                                 sm_dprintf("milter_data: eoh\n");
3581
3582                         /* send it over */
3583                         response = milter_send_command(m, SMFIC_EOH, NULL, 0,
3584                                                        e, state);
3585                         MILTER_CHECK_RESULTS();
3586                 }
3587
3588                 /* check if filter wants the body */
3589                 if (!bitset(SMFIP_NOBODY, m->mf_pflags) &&
3590                     e->e_dfp != NULL)
3591                 {
3592                         rewind = true;
3593                         response = milter_body(m, e, state);
3594                         MILTER_CHECK_RESULTS();
3595                 }
3596
3597                 /* send the final body chunk */
3598                 (void) milter_write(m, SMFIC_BODYEOB, NULL, 0,
3599                                     m->mf_timeout[SMFTO_WRITE], e);
3600
3601                 /* Get time EOM sent for timeout */
3602                 eomsent = curtime();
3603
3604                 /* deal with the possibility of multiple responses */
3605                 while (*state == SMFIR_CONTINUE)
3606                 {
3607                         /* Check total timeout from EOM to final ACK/NAK */
3608                         if (m->mf_timeout[SMFTO_EOM] > 0 &&
3609                             curtime() - eomsent >= m->mf_timeout[SMFTO_EOM])
3610                         {
3611                                 if (tTd(64, 5))
3612                                         sm_dprintf("milter_data(%s): EOM ACK/NAK timeout\n",
3613                                                 m->mf_name);
3614                                 if (MilterLogLevel > 0)
3615                                         sm_syslog(LOG_ERR, e->e_id,
3616                                                   "milter_data(%s): EOM ACK/NAK timeout",
3617                                                   m->mf_name);
3618                                 milter_error(m, e);
3619                                 MILTER_CHECK_ERROR(false, break);
3620                                 break;
3621                         }
3622
3623                         response = milter_read(m, &rcmd, &rlen,
3624                                                m->mf_timeout[SMFTO_READ], e);
3625                         if (m->mf_state == SMFS_ERROR)
3626                                 break;
3627
3628                         if (tTd(64, 10))
3629                                 sm_dprintf("milter_data(%s): state %c\n",
3630                                            m->mf_name, (char) rcmd);
3631
3632                         switch (rcmd)
3633                         {
3634                           case SMFIR_REPLYCODE:
3635                                 MILTER_CHECK_REPLYCODE("554 5.7.1 Command rejected");
3636                                 if (MilterLogLevel > 12)
3637                                         sm_syslog(LOG_INFO, e->e_id, "milter=%s, reject=%s",
3638                                                   m->mf_name, response);
3639                                 *state = rcmd;
3640                                 m->mf_state = SMFS_DONE;
3641                                 break;
3642
3643                           case SMFIR_REJECT: /* log msg at end of function */
3644                                 if (MilterLogLevel > 12)
3645                                         sm_syslog(LOG_INFO, e->e_id, "milter=%s, reject",
3646                                                   m->mf_name);
3647                                 *state = rcmd;
3648                                 m->mf_state = SMFS_DONE;
3649                                 break;
3650
3651                           case SMFIR_DISCARD:
3652                                 if (MilterLogLevel > 12)
3653                                         sm_syslog(LOG_INFO, e->e_id, "milter=%s, discard",
3654                                                   m->mf_name);
3655                                 *state = rcmd;
3656                                 m->mf_state = SMFS_DONE;
3657                                 break;
3658
3659                           case SMFIR_TEMPFAIL:
3660                                 if (MilterLogLevel > 12)
3661                                         sm_syslog(LOG_INFO, e->e_id, "milter=%s, tempfail",
3662                                                   m->mf_name);
3663                                 *state = rcmd;
3664                                 m->mf_state = SMFS_DONE;
3665                                 break;
3666
3667                           case SMFIR_CONTINUE:
3668                           case SMFIR_ACCEPT:
3669                                 /* this filter is done with message */
3670                                 if (replfailed)
3671                                         *state = SMFIR_TEMPFAIL;
3672                                 else
3673                                         *state = SMFIR_ACCEPT;
3674                                 m->mf_state = SMFS_DONE;
3675                                 break;
3676
3677                           case SMFIR_PROGRESS:
3678                                 break;
3679
3680 # if _FFR_QUARANTINE
3681                           case SMFIR_QUARANTINE:
3682                                 if (!bitset(SMFIF_QUARANTINE, m->mf_fflags))
3683                                 {
3684                                         if (MilterLogLevel > 9)
3685                                                 sm_syslog(LOG_WARNING, e->e_id,
3686                                                           "milter_data(%s): lied about quarantining, honoring request anyway",
3687                                                           m->mf_name);
3688                                 }
3689                                 if (response == NULL)
3690                                         response = newstr("");
3691                                 if (MilterLogLevel > 3)
3692                                         sm_syslog(LOG_INFO, e->e_id,
3693                                                   "milter=%s, quarantine=%s",
3694                                                   m->mf_name, response);
3695                                 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool,
3696                                                                  response);
3697                                 macdefine(&e->e_macro, A_PERM,
3698                                           macid("{quarantine}"), e->e_quarmsg);
3699                                 break;
3700 # endif /* _FFR_QUARANTINE */
3701
3702                           case SMFIR_ADDHEADER:
3703                                 if (!bitset(SMFIF_ADDHDRS, m->mf_fflags))
3704                                 {
3705                                         if (MilterLogLevel > 9)
3706                                                 sm_syslog(LOG_WARNING, e->e_id,
3707                                                           "milter_data(%s): lied about adding headers, honoring request anyway",
3708                                                           m->mf_name);
3709                                 }
3710                                 milter_addheader(response, rlen, e);
3711                                 break;
3712
3713                           case SMFIR_CHGHEADER:
3714                                 if (!bitset(SMFIF_CHGHDRS, m->mf_fflags))
3715                                 {
3716                                         if (MilterLogLevel > 9)
3717                                                 sm_syslog(LOG_WARNING, e->e_id,
3718                                                           "milter_data(%s): lied about changing headers, honoring request anyway",
3719                                                           m->mf_name);
3720                                 }
3721                                 milter_changeheader(response, rlen, e);
3722                                 break;
3723
3724                           case SMFIR_ADDRCPT:
3725                                 if (!bitset(SMFIF_ADDRCPT, m->mf_fflags))
3726                                 {
3727                                         if (MilterLogLevel > 9)
3728                                                 sm_syslog(LOG_WARNING, e->e_id,
3729                                                           "milter_data(%s) lied about adding recipients, honoring request anyway",
3730                                                           m->mf_name);
3731                                 }
3732                                 milter_addrcpt(response, rlen, e);
3733                                 break;
3734
3735                           case SMFIR_DELRCPT:
3736                                 if (!bitset(SMFIF_DELRCPT, m->mf_fflags))
3737                                 {
3738                                         if (MilterLogLevel > 9)
3739                                                 sm_syslog(LOG_WARNING, e->e_id,
3740                                                           "milter_data(%s): lied about removing recipients, honoring request anyway",
3741                                                           m->mf_name);
3742                                 }
3743                                 milter_delrcpt(response, rlen, e);
3744                                 break;
3745
3746                           case SMFIR_REPLBODY:
3747                                 if (!bitset(SMFIF_MODBODY, m->mf_fflags))
3748                                 {
3749                                         if (MilterLogLevel > 9)
3750                                                 sm_syslog(LOG_ERR, e->e_id,
3751                                                           "milter_data(%s): lied about replacing body, rejecting request and tempfailing message",
3752                                                           m->mf_name);
3753                                         replfailed = true;
3754                                         break;
3755                                 }
3756
3757                                 /* already failed in attempt */
3758                                 if (replfailed)
3759                                         break;
3760
3761                                 if (!dfopen)
3762                                 {
3763                                         if (milter_reopen_df(e) < 0)
3764                                         {
3765                                                 replfailed = true;
3766                                                 break;
3767                                         }
3768                                         dfopen = true;
3769                                         rewind = true;
3770                                 }
3771
3772                                 if (milter_replbody(response, rlen,
3773                                                     newfilter, e) < 0)
3774                                         replfailed = true;
3775                                 newfilter = false;
3776                                 replbody = true;
3777                                 break;
3778
3779                           default:
3780                                 /* Invalid response to command */
3781                                 if (MilterLogLevel > 0)
3782                                         sm_syslog(LOG_ERR, e->e_id,
3783                                                   "milter_data(%s): returned bogus response %c",
3784                                                   m->mf_name, rcmd);
3785                                 milter_error(m, e);
3786                                 break;
3787                         }
3788                         if (rcmd != SMFIR_REPLYCODE && response != NULL)
3789                         {
3790                                 sm_free(response); /* XXX */
3791                                 response = NULL;
3792                         }
3793
3794                         if (m->mf_state == SMFS_ERROR)
3795                                 break;
3796                 }
3797
3798                 if (replbody && !replfailed)
3799                 {
3800                         /* flush possible buffered character */
3801                         milter_replbody(NULL, 0, !replbody, e);
3802                         replbody = false;
3803                 }
3804
3805                 if (m->mf_state == SMFS_ERROR)
3806                 {
3807                         MILTER_CHECK_ERROR(false, continue);
3808                         goto finishup;
3809                 }
3810         }
3811
3812 finishup:
3813         /* leave things in the expected state if we touched it */
3814         if (replfailed)
3815         {
3816                 if (*state == SMFIR_CONTINUE ||
3817                     *state == SMFIR_ACCEPT)
3818                 {
3819                         *state = SMFIR_TEMPFAIL;
3820                         SM_FREE_CLR(response);
3821                 }
3822
3823                 if (dfopen)
3824                 {
3825                         (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT);
3826                         e->e_dfp = NULL;
3827                         e->e_flags &= ~EF_HAS_DF;
3828                         dfopen = false;
3829                 }
3830                 rewind = false;
3831         }
3832
3833         if ((dfopen && milter_reset_df(e) < 0) ||
3834             (rewind && bfrewind(e->e_dfp) < 0))
3835         {
3836                 save_errno = errno;
3837                 ExitStat = EX_IOERR;
3838
3839                 /*
3840                 **  If filter told us to keep message but we had
3841                 **  an error, we can't really keep it, tempfail it.
3842                 */
3843
3844                 if (*state == SMFIR_CONTINUE ||
3845                     *state == SMFIR_ACCEPT)
3846                 {
3847                         *state = SMFIR_TEMPFAIL;
3848                         SM_FREE_CLR(response);
3849                 }
3850
3851                 errno = save_errno;
3852                 syserr("milter_data: %s/%cf%s: read error",
3853                        qid_printqueue(e->e_qgrp, e->e_qdir),
3854                        DATAFL_LETTER, e->e_id);
3855         }
3856
3857         MILTER_CHECK_DONE_MSG();
3858         if (MilterLogLevel > 10 && *state == SMFIR_REJECT)
3859                 sm_syslog(LOG_INFO, e->e_id, "Milter: reject, data");
3860         return response;
3861 }
3862 /*
3863 **  MILTER_QUIT -- informs the filter(s) we are done and closes connection(s)
3864 **
3865 **      Parameters:
3866 **              e -- current envelope.
3867 **
3868 **      Returns:
3869 **              none
3870 */
3871
3872 void
3873 milter_quit(e)
3874         ENVELOPE *e;
3875 {
3876         int i;
3877
3878         if (tTd(64, 10))
3879                 sm_dprintf("milter_quit(%s)\n", e->e_id);
3880
3881         for (i = 0; InputFilters[i] != NULL; i++)
3882                 milter_quit_filter(InputFilters[i], e);
3883 }
3884 /*
3885 **  MILTER_ABORT -- informs the filter(s) that we are aborting current message
3886 **
3887 **      Parameters:
3888 **              e -- current envelope.
3889 **
3890 **      Returns:
3891 **              none
3892 */
3893
3894 void
3895 milter_abort(e)
3896         ENVELOPE *e;
3897 {
3898         int i;
3899
3900         if (tTd(64, 10))
3901                 sm_dprintf("milter_abort\n");
3902
3903         for (i = 0; InputFilters[i] != NULL; i++)
3904         {
3905                 struct milter *m = InputFilters[i];
3906
3907                 /* sanity checks */
3908                 if (m->mf_sock < 0 || m->mf_state != SMFS_INMSG)
3909                         continue;
3910
3911                 milter_abort_filter(m, e);
3912         }
3913 }
3914 #endif /* MILTER */