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