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