bmf-milter

bmf filter milter daemon
git clone git://r-36.net/bmf-milter
Log | Files | Refs | LICENSE

commit b334fc80bdfd47b8e0099fda769b148e7fb00b14
parent 3dd1bce69f1e8a4c58e32f00ebef05ed8f852b1a
Author: Christoph Lohmann <20h@r-36.net>
Date:   Mon, 17 Aug 2020 11:28:27 +0200

Only start bmf when there is content.

* Reduce resource usage by tenfold.
* Solve problem of bmf instances not killed when there was only helo.

Diffstat:
bmf-milter.c | 200++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
1 file changed, 126 insertions(+), 74 deletions(-)

diff --git a/bmf-milter.c b/bmf-milter.c @@ -39,83 +39,32 @@ struct Priv { #define MLFIPRIV ((struct Priv *) smfi_getpriv(ctx)) -sfsistat -mlfi_cleanup(SMFICTX *ctx, int iseom) -{ - struct Priv *priv = MLFIPRIV; - int retcode = -1; - - if (dodebug) - fprintf(stderr, "mlfi_cleanup\n"); - - if (priv == NULL) - return SMFIS_CONTINUE; - if (dodebug) - fprintf(stderr, "cleanup: closing execpipe[1]\n"); - close(priv->execpipe[1]); - priv->execpipe[1] = -1; - if (dodebug) - fprintf(stderr, "cleanup: waitpid\n"); - waitpid(priv->execpid, &retcode, 0); - if (dodebug) - fprintf(stderr, "cleanup: retcode = %d\n", retcode); - - /* - * smfi_addheader is only allowed in eom. - */ - if (iseom) { - if (retcode == 0) { - if (smfi_addheader(ctx, "X-Spam-Flag", - " YES") == MI_FAILURE) { - if (dodebug) - fprintf(stderr, "x-spam-flag failed\n"); - } - } - if (smfi_addheader(ctx, "X-BMF-Processed", - " YES") == MI_FAILURE) { - if (dodebug) - fprintf(stderr, "x-bmf-processed failed\n"); - } - } - - return SMFIS_CONTINUE; -} - -sfsistat -mlfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr) -{ - if (dodebug) - fprintf(stderr, "mlfi_connect(%s)\n", hostname); - - return SMFIS_CONTINUE; -} - -sfsistat -mlfi_helo(SMFICTX *ctx, char *helohost) +int +start_bmf(SMFICTX *ctx) { struct Priv *priv; char *ident, *bmfargs[6]; int pid, nullfd, argp; if (dodebug) - fprintf(stderr, "mlfi_helo(%s)\n", helohost); + fprintf(stderr, "start_bmf()\n"); if (donothing) { smfi_setpriv(ctx, NULL); - return SMFIS_CONTINUE; + return 1; } - priv = malloc(sizeof *priv); + priv = malloc(sizeof(*priv)); if (priv == NULL) - return SMFIS_CONTINUE; - memset(priv, '\0', sizeof *priv); + return 1; + memset(priv, '\0', sizeof(*priv)); smfi_setpriv(ctx, priv); if (pipe(priv->execpipe) < 0) { free(priv); smfi_setpriv(ctx, NULL); - return SMFIS_CONTINUE; + return 1; } switch ((pid = fork())) { @@ -160,11 +109,79 @@ mlfi_helo(SMFICTX *ctx, char *helohost) smfi_setpriv(ctx, NULL); break; default: + if (dodebug) + fprintf(stderr, "start_bmf(pid = %d)\n", pid); priv->execpid = pid; close(priv->execpipe[0]); break; } + return 0; +} + +sfsistat +mlfi_cleanup(SMFICTX *ctx, int iseom) +{ + struct Priv *priv = MLFIPRIV; + int retcode = -1; + + if (dodebug) + fprintf(stderr, "mlfi_cleanup(iseom = %d)\n", iseom); + + if (priv == NULL) + return SMFIS_CONTINUE; + if (dodebug) + fprintf(stderr, "mlfi_cleanup(closing execpipe[1])\n"); + close(priv->execpipe[1]); + priv->execpipe[1] = -1; + if (dodebug) + fprintf(stderr, "mlfi_cleanup(waitpid)\n"); + waitpid(priv->execpid, &retcode, 0); + if (dodebug) + fprintf(stderr, "mlfi_cleanup(retcode = %d)\n", retcode); + + /* + * smfi_addheader is only allowed in eom. + */ + if (iseom) { + if (retcode == 0) { + if (smfi_addheader(ctx, "X-Spam-Flag", + " YES") == MI_FAILURE) { + if (dodebug) { + fprintf(stderr, + "mlfi_cleanup(x-spam-flag failed)\n"); + } + } + } + if (smfi_addheader(ctx, "X-BMF-Processed", + " YES") == MI_FAILURE) { + if (dodebug) { + fprintf(stderr, + "mlfi_cleanup(x-bmf-processed failed)\n"); + } + } + } + + return SMFIS_CONTINUE; +} + +sfsistat +mlfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr) +{ + if (dodebug) + fprintf(stderr, "mlfi_connect(%s)\n", hostname); + + return SMFIS_CONTINUE; +} + +sfsistat +mlfi_helo(SMFICTX *ctx, char *helohost) +{ + if (dodebug) + fprintf(stderr, "mlfi_helo(%s)\n", helohost); + + smfi_setpriv(ctx, NULL); + return SMFIS_CONTINUE; } @@ -176,6 +193,11 @@ mlfi_envfrom(SMFICTX *ctx, char *argv[]) if (dodebug) fprintf(stderr, "mlfi_envfrom(%s)\n", argv[0]); + if (priv == NULL) { + if (start_bmf(ctx)) + return SMFIS_CONTINUE; + priv = MLFIPRIV; + } dprintf(priv->execpipe[1], "From: %s\n", argv[0]); return SMFIS_CONTINUE; @@ -187,8 +209,13 @@ mlfi_envrcpt(SMFICTX *ctx, char *argv[]) struct Priv *priv = MLFIPRIV; if (dodebug) - fprintf(stderr, "mfli_envrcpt(%s)\n", argv[0]); + fprintf(stderr, "mlfi_envrcpt(%s)\n", argv[0]); + if (priv == NULL) { + if (start_bmf(ctx)) + return SMFIS_CONTINUE; + priv = MLFIPRIV; + } dprintf(priv->execpipe[1], "To: %s\n", argv[0]); return SMFIS_CONTINUE; @@ -202,7 +229,12 @@ mlfi_header(SMFICTX *ctx, char *headerf, char *headerv) if (dodebug) fprintf(stderr, "mlfi_header(%s = '%s')\n", headerf, headerv); - dprintf(priv->execpipe[1], "%s: %s\n", headerf, headerv); + if (priv == NULL) { + if (start_bmf(ctx)) + return SMFIS_CONTINUE; + priv = MLFIPRIV; + } + dprintf(priv->execpipe[1], "%s:%s\n", headerf, headerv); return SMFIS_CONTINUE; } @@ -213,8 +245,13 @@ mlfi_eoh(SMFICTX *ctx) struct Priv *priv = MLFIPRIV; if (dodebug) - fprintf(stderr, "mlfi_eoh\n"); + fprintf(stderr, "mlfi_eoh()\n"); + if (priv == NULL) { + if (start_bmf(ctx)) + return SMFIS_CONTINUE; + priv = MLFIPRIV; + } dprintf(priv->execpipe[1], "\r\n"); return SMFIS_CONTINUE; @@ -229,6 +266,11 @@ mlfi_body(SMFICTX *ctx, unsigned char *bodyp, size_t bodylen) if (dodebug) fprintf(stderr, "mlfi_body(%ld bytes)\n", bodylen); + if (priv == NULL) { + if (start_bmf(ctx)) + return SMFIS_CONTINUE; + priv = MLFIPRIV; + } for (int written = 0, rw = 0; written < bodylen; written += rw) rw = write(priv->execpipe[1], bodyp+written, bodylen-written); @@ -239,7 +281,7 @@ sfsistat mlfi_eom(SMFICTX *ctx) { if (dodebug) - fprintf(stderr, "mlfi_eom\n"); + fprintf(stderr, "mlfi_eom()\n"); return mlfi_cleanup(ctx, 1); } @@ -248,7 +290,7 @@ sfsistat mlfi_abort(SMFICTX *ctx) { if (dodebug) - fprintf(stderr, "mlfi_abort\n"); + fprintf(stderr, "mlfi_abort()\n"); return mlfi_cleanup(ctx, 0); } @@ -259,22 +301,26 @@ mlfi_close(SMFICTX *ctx) struct Priv *priv = MLFIPRIV; if (dodebug) - fprintf(stderr, "mlfi_close\n"); + fprintf(stderr, "mlfi_close()\n"); if (priv != NULL) { if (priv->execpipe[1] > 0) { - if (dodebug) - fprintf(stderr, "Close execpipe[1]\n"); + if (dodebug) { + fprintf(stderr, + "mlfi_close(close execpipe[1])\n"); + } close(priv->execpipe[1]); } if (priv->execpid > 0) { - if (dodebug) - fprintf(stderr, "Kill pid %d.\n", priv->execpid); + if (dodebug) { + fprintf(stderr, + "mlfi_close(kill pid %d)\n", priv->execpid); + } kill(priv->execpid, SIGKILL); waitpid(priv->execpid, NULL, 0); } if (dodebug) - fprintf(stderr, "Free priv\n"); + fprintf(stderr, "mlfi_close(free priv)\n"); free(priv); smfi_setpriv(ctx, NULL); } @@ -294,7 +340,7 @@ mlfi_negotiate(SMFICTX *ctx, unsigned long *pf3) { if (dodebug) - fprintf(stderr, "mlfi_negotiate\n"); + fprintf(stderr, "mlfi_negotiate()\n"); /* milter actions */ *pf0 = 0; @@ -464,17 +510,23 @@ main(int argc, char *argv[]) } if (gr != NULL) { - if (setgroups(1, &gr->gr_gid) != 0 || setgid(gr->gr_gid) != 0) + if (setgroups(1, &gr->gr_gid) != 0 || setgid(gr->gr_gid) != 0) { + perror("setgroups"); return -1; + } } if (us != NULL) { if (gr == NULL) { if (setgroups(1, &us->pw_gid) != 0 || - setgid(us->pw_gid) != 0) + setgid(us->pw_gid) != 0) { + perror("setgroups"); return -1; + } } - if (setuid(us->pw_uid) != 0) + if (setuid(us->pw_uid) != 0) { + perror("setuid"); return -1; + } } if (smfi_setconn(conndef) == MI_FAILURE) {