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