aboutsummaryrefslogtreecommitdiffstats
path: root/mailtrain.c
diff options
context:
space:
mode:
Diffstat (limited to 'mailtrain.c')
-rw-r--r--mailtrain.c352
1 files changed, 0 insertions, 352 deletions
diff --git a/mailtrain.c b/mailtrain.c
deleted file mode 100644
index 41071bc..0000000
--- a/mailtrain.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * mailing backend for dovecot antispam plugin
- *
- * Copyright (C) 2007 Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/wait.h>
-#include <fcntl.h>
-
-#include "lib.h"
-#include "dict.h"
-#include "mail-storage-private.h"
-#include "ostream.h"
-#include "istream.h"
-
-#include "antispam-plugin.h"
-
-static const char *spamaddr = NULL;
-static const char *hamaddr = NULL;
-static const char *sendmail_binary = "/usr/sbin/sendmail";
-static const char *tmpdir = "/tmp";
-static char **extra_args = NULL;
-static int extra_args_num = 0;
-
-static int run_sendmail(int mailfd, enum classification wanted)
-{
- const char *dest;
- pid_t pid;
- int status;
-
- switch (wanted) {
- case CLASS_SPAM:
- dest = spamaddr;
- break;
- case CLASS_NOTSPAM:
- dest = hamaddr;
- break;
- }
-
- if (!dest)
- return -1;
-
- pid = fork();
-
- if (pid == -1)
- return -1;
-
- debug("running mailtrain backend program %s", sendmail_binary);
-
- if (pid) {
- if (waitpid(pid, &status, 0) == -1)
- return -1;
- if (!WIFEXITED(status))
- return -1;
- return WEXITSTATUS(status);
- } else {
- char **argv;
- int sz = sizeof(char *) * (2 + extra_args_num + 1);
- int i;
-
- argv = i_malloc(sz);
- memset(argv, 0, sz);
-
- argv[0] = (char *) sendmail_binary;
-
- for (i = 0; i < extra_args_num; i++)
- argv[i + 1] = (char *) extra_args[i];
-
- argv[i + 1] = (char *) dest;
-
- dup2(mailfd, 0);
- close(1);
- close(2);
- execv(sendmail_binary, argv);
- _exit(1);
- /* not reached */
- return -1;
- }
-}
-
-struct antispam_transaction_context {
- char *tmpdir;
- int count;
- int tmplen;
-};
-
-struct antispam_transaction_context *
-backend_start(struct mailbox *box __attr_unused__)
-{
- struct antispam_transaction_context *ast;
- char *tmp;
-
- ast = i_new(struct antispam_transaction_context, 1);
-
- ast->count = 0;
-
- tmp = i_strconcat(tmpdir, "/antispam-mail-XXXXXX", NULL);
-
- ast->tmpdir = mkdtemp(tmp);
- if (!ast->tmpdir)
- i_free(tmp);
- else
- ast->tmplen = strlen(ast->tmpdir);
-
- return ast;
-}
-
-static int process_tmpdir(struct mailbox_transaction_context *ctx,
- struct antispam_transaction_context *ast)
-{
- int cnt = ast->count;
- int fd;
- char *buf;
- enum classification wanted;
- int rc = 0;
-
- t_push();
-
- buf = t_malloc(20 + ast->tmplen);
-
- while (rc == 0 && cnt > 0) {
- cnt--;
- i_snprintf(buf, 20 + ast->tmplen - 1, "%s/%d",
- ast->tmpdir, cnt);
-
- fd = open(buf, O_RDONLY);
- read(fd, &wanted, sizeof(wanted));
-
- if ((rc = run_sendmail(fd, wanted))) {
- mail_storage_set_error(ctx->box->storage,
- ME(TEMP)
- "failed to send mail");
- debug("run program failed with exit code %d\n", rc);
- rc = -1;
- }
-
- close(fd);
- }
-
- t_pop();
-
- return rc;
-}
-
-static void clear_tmpdir(struct antispam_transaction_context *ast)
-{
- char *buf;
-
- t_push();
-
- buf = t_malloc(20 + ast->tmplen);
-
- while (ast->count > 0) {
- ast->count--;
- i_snprintf(buf, 20 + ast->tmplen - 1, "%s/%d",
- ast->tmpdir, ast->count);
- unlink(buf);
- }
- rmdir(ast->tmpdir);
-
- t_pop();
-}
-
-void backend_rollback(struct antispam_transaction_context *ast)
-{
- if (ast->tmpdir) {
- /* clear it! */
- clear_tmpdir(ast);
- i_free(ast->tmpdir);
- }
-
- i_free(ast);
-}
-
-int backend_commit(struct mailbox_transaction_context *ctx,
- struct antispam_transaction_context *ast)
-{
- int ret;
-
- if (!ast->tmpdir) {
- i_free(ast);
- return 0;
- }
-
- ret = process_tmpdir(ctx, ast);
-
- clear_tmpdir(ast);
-
- i_free(ast->tmpdir);
- i_free(ast);
-
- return ret;
-}
-
-int backend_handle_mail(struct mailbox_transaction_context *t,
- struct antispam_transaction_context *ast,
- struct mail *mail, enum classification wanted)
-{
- struct istream *mailstream;
- struct ostream *outstream;
- int ret;
- char *buf;
- const unsigned char *beginning;
- size_t size;
- int fd;
-
- if (!ast->tmpdir) {
- mail_storage_set_error(t->box->storage,
- ME(NOTPOSSIBLE)
- "Failed to initialise temporary dir");
- return -1;
- }
-
- if (!hamaddr || !spamaddr) {
- mail_storage_set_error(t->box->storage,
- ME(NOTPOSSIBLE)
- "antispam plugin not configured");
- return -1;
- }
-
- mailstream = get_mail_stream(mail);
- if (!mailstream) {
- mail_storage_set_error(t->box->storage,
- ME(EXPUNGED)
- "Failed to get mail contents");
- return -1;
- }
-
- t_push();
-
- buf = t_malloc(20 + ast->tmplen);
- i_snprintf(buf, 20 + ast->tmplen - 1, "%s/%d", ast->tmpdir, ast->count);
-
- fd = creat(buf, 0600);
- if (fd < 0) {
- mail_storage_set_error(t->box->storage,
- ME(NOTPOSSIBLE)
- "Failed to create temporary file");
- ret = -1;
- goto out;
- }
-
- ast->count++;
-
- outstream = o_stream_create_from_fd(fd, t->box->pool);
- if (!outstream) {
- ret = -1;
- mail_storage_set_error(t->box->storage,
- ME(NOTPOSSIBLE)
- "Failed to stream temporary file");
- goto out_close;
- }
-
- if (o_stream_send(outstream, &wanted, sizeof(wanted))
- != sizeof(wanted)) {
- ret = -1;
- mail_storage_set_error(t->box->storage,
- ME(NOTPOSSIBLE)
- "Failed to write marker to temp file");
- goto failed_to_copy;
- }
-
- if (i_stream_read_data(mailstream, &beginning, &size, 5) < 0 ||
- size < 5) {
- ret = -1;
- mail_storage_set_error(t->box->storage,
- ME(NOTPOSSIBLE)
- "Failed to read mail beginning");
- goto failed_to_copy;
- }
-
- /* "From "? skip line */
- if (memcmp("From ", beginning, 5) == 0)
- i_stream_read_next_line(mailstream);
-
- if (o_stream_send_istream(outstream, mailstream) < 0) {
- ret = -1;
- mail_storage_set_error(t->box->storage,
- ME(NOTPOSSIBLE)
- "Failed to copy to temporary file");
- goto failed_to_copy;
- }
-
- ret = 0;
-
- failed_to_copy:
- o_stream_destroy(&outstream);
- out_close:
- close(fd);
- out:
- t_pop();
-
- return ret;
-}
-
-void backend_init(pool_t pool __attr_unused__)
-{
- const char *tmp;
- int i;
-
- tmp = get_setting("MAIL_SPAM");
- if (tmp) {
- spamaddr = tmp;
- debug("mail backend spam address %s\n", tmp);
- }
-
- tmp = get_setting("MAIL_NOTSPAM");
- if (tmp) {
- hamaddr = tmp;
- debug("mail backend not-spam address %s\n", tmp);
- }
-
- tmp = get_setting("MAIL_SENDMAIL");
- if (tmp) {
- sendmail_binary = tmp;
- debug("mail backend sendmail %s\n", tmp);
- }
-
- tmp = get_setting("MAIL_SENDMAIL_ARGS");
- if (tmp) {
- extra_args = p_strsplit(pool, tmp, ";");
- extra_args_num = str_array_length(
- (const char *const *)extra_args);
- for (i = 0; i < extra_args_num; i++)
- debug("mail backend sendmail arg %s\n",
- extra_args[i]);
- }
-
- tmp = get_setting("MAIL_TMPDIR");
- if (tmp)
- tmpdir = tmp;
- debug("mail backend tmpdir %s\n", tmpdir);
-}
-
-void backend_exit(void)
-{
-}