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