aboutsummaryrefslogtreecommitdiffstats
path: root/extras/filters/filter-python/filter_python.c
diff options
context:
space:
mode:
Diffstat (limited to 'extras/filters/filter-python/filter_python.c')
-rw-r--r--extras/filters/filter-python/filter_python.c539
1 files changed, 0 insertions, 539 deletions
diff --git a/extras/filters/filter-python/filter_python.c b/extras/filters/filter-python/filter_python.c
deleted file mode 100644
index 33c1f4b..0000000
--- a/extras/filters/filter-python/filter_python.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * Copyright (c) 2014 Gilles Chehade <gilles@poolp.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "includes.h"
-
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <inttypes.h>
-#include <stdio.h>
-#include <unistd.h>
-
-/* _GNU_SOURCE is not properly protected in Python.h ... */
-#undef _GNU_SOURCE
-#include <Python.h>
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <smtpd-api.h>
-
-static PyObject *py_on_connect;
-static PyObject *py_on_helo;
-static PyObject *py_on_mail;
-static PyObject *py_on_rcpt;
-static PyObject *py_on_data;
-static PyObject *py_on_eom;
-static PyObject *py_on_dataline;
-
-static PyObject *py_on_tx_begin;
-static PyObject *py_on_tx_commit;
-static PyObject *py_on_tx_rollback;
-static PyObject *py_on_disconnect;
-
-
-static PyObject *
-py_filter_accept(PyObject *self, PyObject *args)
-{
- uint64_t id;
-
- if (!PyArg_ParseTuple(args, "K", &id))
- return NULL;
- filter_api_accept(id);
- Py_RETURN_TRUE;
-}
-
-static PyObject *
-py_filter_reject(PyObject *self, PyObject *args)
-{
- uint64_t id;
- uint32_t action;
-
- if (!PyArg_ParseTuple(args, "Ki", &id, &action))
- return NULL;
-
- switch (action) {
- case FILTER_FAIL:
- case FILTER_CLOSE:
- filter_api_reject(id, action);
- Py_RETURN_TRUE;
- break;
- }
- Py_RETURN_FALSE;
-}
-
-static PyObject *
-py_filter_reject_code(PyObject *self, PyObject *args)
-{
- uint64_t id;
- uint32_t action;
- uint32_t code;
- const char *line;
-
- if (!PyArg_ParseTuple(args, "Kiis", &id, &action, &code, &line))
- return NULL;
-
- switch (action) {
- case FILTER_FAIL:
- case FILTER_CLOSE:
- filter_api_reject_code(id, action, code, line);
- Py_RETURN_TRUE;
- break;
- }
- Py_RETURN_FALSE;
-}
-
-static PyObject *
-py_filter_writeln(PyObject *self, PyObject *args)
-{
- uint64_t id;
- const char *line;
-
- if (!PyArg_ParseTuple(args, "Ks", &id, &line))
- return NULL;
- filter_api_writeln(id, line);
- Py_RETURN_TRUE;
-}
-
-static PyMethodDef py_methods[] = {
- { "accept", py_filter_accept, METH_VARARGS, "accept" },
- { "reject", py_filter_reject, METH_VARARGS, "reject" },
- { "reject_code", py_filter_reject_code, METH_VARARGS, "reject_code" },
- { "writeln", py_filter_writeln, METH_VARARGS, "writeln" },
- { NULL, NULL, 0, NULL }
-};
-
-
-static int
-on_connect(uint64_t id, struct filter_connect *conn)
-{
- PyObject *py_args;
- PyObject *py_ret;
- PyObject *py_id;
- PyObject *py_local;
- PyObject *py_remote;
- PyObject *py_hostname;
-
- py_args = PyTuple_New(4);
- py_id = PyLong_FromUnsignedLongLong(id);
- py_local = PyString_FromString(filter_api_sockaddr_to_text((struct sockaddr *)&conn->local));
- py_remote = PyString_FromString(filter_api_sockaddr_to_text((struct sockaddr *)&conn->remote));
- py_hostname = PyString_FromString(conn->hostname);
-
- PyTuple_SetItem(py_args, 0, py_id);
- PyTuple_SetItem(py_args, 1, py_local);
- PyTuple_SetItem(py_args, 2, py_remote);
- PyTuple_SetItem(py_args, 3, py_hostname);
-
- py_ret = PyObject_CallObject(py_on_connect, py_args);
- Py_DECREF(py_args);
-
- if (py_ret == NULL) {
- PyErr_Print();
- log_warnx("warn: on_connect: handler failed");
- exit(1);
- }
-
- return 1;
-}
-
-static int
-on_helo(uint64_t id, const char *helo)
-{
- PyObject *py_args;
- PyObject *py_ret;
- PyObject *py_id;
- PyObject *py_helo;
-
- py_args = PyTuple_New(2);
- py_id = PyLong_FromUnsignedLongLong(id);
- py_helo = PyString_FromString(helo);
-
- PyTuple_SetItem(py_args, 0, py_id);
- PyTuple_SetItem(py_args, 1, py_helo);
-
- py_ret = PyObject_CallObject(py_on_helo, py_args);
- Py_DECREF(py_args);
- if (py_ret == NULL) {
- PyErr_Print();
- log_warnx("warn: on_helo: handler failed");
- exit(1);
- }
- return 1;
-}
-
-static int
-on_mail(uint64_t id, struct mailaddr *mail)
-{
- PyObject *py_args;
- PyObject *py_ret;
- PyObject *py_id;
- PyObject *py_sender;
-
- py_args = PyTuple_New(2);
- py_id = PyLong_FromUnsignedLongLong(id);
- py_sender = PyString_FromString(filter_api_mailaddr_to_text(mail));
-
- PyTuple_SetItem(py_args, 0, py_id);
- PyTuple_SetItem(py_args, 1, py_sender);
-
- py_ret = PyObject_CallObject(py_on_mail, py_args);
- Py_DECREF(py_args);
-
- if (py_ret == NULL) {
- PyErr_Print();
- log_warnx("warn: on_mail: handler failed");
- exit(1);
- }
-
- return 1;
-}
-
-static int
-on_rcpt(uint64_t id, struct mailaddr *rcpt)
-{
- PyObject *py_args;
- PyObject *py_ret;
- PyObject *py_id;
- PyObject *py_rcpt;
-
- py_args = PyTuple_New(2);
- py_id = PyLong_FromUnsignedLongLong(id);
- py_rcpt = PyString_FromString(filter_api_mailaddr_to_text(rcpt));
-
- PyTuple_SetItem(py_args, 0, py_id);
- PyTuple_SetItem(py_args, 1, py_rcpt);
-
- py_ret = PyObject_CallObject(py_on_rcpt, py_args);
- Py_DECREF(py_args);
-
- if (py_ret == NULL) {
- PyErr_Print();
- log_warnx("warn: on_rcpt: handler failed");
- exit(1);
- }
-
- return 1;
-}
-
-static int
-on_data(uint64_t id)
-{
- PyObject *py_args;
- PyObject *py_ret;
- PyObject *py_id;
-
- py_args = PyTuple_New(1);
- py_id = PyLong_FromUnsignedLongLong(id);
- PyTuple_SetItem(py_args, 0, py_id);
- py_ret = PyObject_CallObject(py_on_data, py_args);
- Py_DECREF(py_args);
-
- if (py_ret == NULL) {
- PyErr_Print();
- log_warnx("warn: on_data: handler failed");
- exit(1);
- }
-
- return 1;
-}
-
-static int
-on_eom(uint64_t id, size_t sz)
-{
- PyObject *py_args;
- PyObject *py_ret;
- PyObject *py_id;
- PyObject *py_sz;
-
- py_args = PyTuple_New(2);
- py_id = PyLong_FromUnsignedLongLong(id);
- py_sz = PyLong_FromSize_t(sz);
- PyTuple_SetItem(py_args, 0, py_id);
- PyTuple_SetItem(py_args, 1, py_sz);
- py_ret = PyObject_CallObject(py_on_eom, py_args);
- Py_DECREF(py_args);
-
- if (py_ret == NULL) {
- PyErr_Print();
- log_warnx("warn: on_eom: handler failed");
- exit(1);
- }
-
- return 1;
-}
-
-static void
-on_tx_begin(uint64_t id)
-{
- PyObject *py_args;
- PyObject *py_ret;
- PyObject *py_id;
-
- py_args = PyTuple_New(1);
- py_id = PyLong_FromUnsignedLongLong(id);
- PyTuple_SetItem(py_args, 0, py_id);
- py_ret = PyObject_CallObject(py_on_tx_begin, py_args);
- Py_DECREF(py_args);
-
- if (py_ret == NULL) {
- PyErr_Print();
- log_warnx("warn: on_tx_begin: handler failed");
- exit(1);
- }
-}
-
-static void
-on_tx_commit(uint64_t id)
-{
- PyObject *py_args;
- PyObject *py_ret;
- PyObject *py_id;
-
- py_args = PyTuple_New(1);
- py_id = PyLong_FromUnsignedLongLong(id);
- PyTuple_SetItem(py_args, 0, py_id);
- py_ret = PyObject_CallObject(py_on_tx_commit, py_args);
- Py_DECREF(py_args);
-
- if (py_ret == NULL) {
- PyErr_Print();
- log_warnx("warn: on_tx_commit: handler failed");
- exit(1);
- }
-}
-
-static void
-on_tx_rollback(uint64_t id)
-{
- PyObject *py_args;
- PyObject *py_ret;
- PyObject *py_id;
-
- py_args = PyTuple_New(1);
- py_id = PyLong_FromUnsignedLongLong(id);
- PyTuple_SetItem(py_args, 0, py_id);
- py_ret = PyObject_CallObject(py_on_tx_rollback, py_args);
- Py_DECREF(py_args);
-
- if (py_ret == NULL) {
- PyErr_Print();
- log_warnx("warn: on_tx_rollback: handler failed");
- exit(1);
- }
-}
-
-static void
-on_disconnect(uint64_t id)
-{
- PyObject *py_args;
- PyObject *py_ret;
- PyObject *py_id;
-
- py_args = PyTuple_New(1);
- py_id = PyLong_FromUnsignedLongLong(id);
- PyTuple_SetItem(py_args, 0, py_id);
- py_ret = PyObject_CallObject(py_on_disconnect, py_args);
- Py_DECREF(py_args);
-
- if (py_ret == NULL) {
- PyErr_Print();
- log_warnx("warn: on_disconnect: handler failed");
- exit(1);
- }
-}
-
-static void
-on_dataline(uint64_t id, const char *line)
-{
- PyObject *py_args;
- PyObject *py_ret;
- PyObject *py_id;
- PyObject *py_line;
-
- py_args = PyTuple_New(2);
- py_id = PyLong_FromUnsignedLongLong(id);
- py_line = PyString_FromString(line);
-
- PyTuple_SetItem(py_args, 0, py_id);
- PyTuple_SetItem(py_args, 1, py_line);
-
- py_ret = PyObject_CallObject(py_on_dataline, py_args);
- Py_DECREF(py_args);
-
- if (py_ret == NULL) {
- PyErr_Print();
- log_warnx("warn: on_dataline: handler failed");
- exit(1);
- }
-}
-
-static char *
-loadfile(const char * path)
-{
- FILE *f;
- off_t oz;
- size_t sz;
- char *buf;
-
- if ((f = fopen(path, "r")) == NULL)
- err(1, "fopen");
-
- if (fseek(f, 0, SEEK_END) == -1)
- err(1, "fseek");
-
- oz = ftello(f);
-
- if (fseek(f, 0, SEEK_SET) == -1)
- err(1, "fseek");
-
- if (oz >= SIZE_MAX)
- errx(1, "too big");
-
- sz = oz;
-
- buf = xmalloc(sz + 1, "loadfile");
-
- if (fread(buf, 1, sz, f) != sz)
- err(1, "fread");
-
- buf[sz] = '\0';
-
- fclose(f);
-
- return buf;
-}
-
-int
-main(int argc, char **argv)
-{
- int ch, d = 0, v = 0;
- char *c = NULL, *path, *buf;
- PyObject *self, *code, *module;
-
- log_init(1);
-
- while ((ch = getopt(argc, argv, "c:dv")) != -1) {
- switch (ch) {
- case 'c':
- c = optarg;
- break;
- case 'd':
- d = 1;
- break;
- case 'v':
- v |= TRACE_DEBUG;
- break;
- default:
- log_warnx("warn: bad option");
- return 1;
- /* NOTREACHED */
- }
- }
- argc -= optind;
- argv += optind;
- if (argc == 0)
- errx(1, "missing path");
-
- if (c)
- c = strip(c);
- path = argv[0];
-
- log_init(d);
- log_verbose(v);
-
- Py_Initialize();
- self = Py_InitModule("filter", py_methods);
- PyModule_AddIntConstant(self, "FILTER_OK", FILTER_OK);
- PyModule_AddIntConstant(self, "FILTER_FAIL", FILTER_FAIL);
- PyModule_AddIntConstant(self, "FILTER_CLOSE", FILTER_CLOSE);
-
- buf = loadfile(path);
- code = Py_CompileString(buf, path, Py_file_input);
- free(buf);
-
- if (code == NULL) {
- PyErr_Print();
- log_warnx("warn: failed to compile %s", path);
- return 1;
- }
-
- module = PyImport_ExecCodeModuleEx("myfilter", code, path);
-
- if (module == NULL) {
- PyErr_Print();
- log_warnx("warn: failed to install module %s", path);
- return 1;
- }
-
- log_debug("debug: starting...");
-
- py_on_connect = PyObject_GetAttrString(module, "on_connect");
- if (py_on_connect && PyCallable_Check(py_on_connect))
- filter_api_on_connect(on_connect);
-
- py_on_helo = PyObject_GetAttrString(module, "on_helo");
- if (py_on_helo && PyCallable_Check(py_on_helo))
- filter_api_on_helo(on_helo);
-
- py_on_mail = PyObject_GetAttrString(module, "on_mail");
- if (py_on_mail && PyCallable_Check(py_on_mail))
- filter_api_on_mail(on_mail);
-
- py_on_rcpt = PyObject_GetAttrString(module, "on_rcpt");
- if (py_on_rcpt && PyCallable_Check(py_on_rcpt))
- filter_api_on_rcpt(on_rcpt);
-
- py_on_data = PyObject_GetAttrString(module, "on_data");
- if (py_on_data && PyCallable_Check(py_on_data))
- filter_api_on_data(on_data);
-
- py_on_eom = PyObject_GetAttrString(module, "on_eom");
- if (py_on_eom && PyCallable_Check(py_on_eom))
- filter_api_on_eom(on_eom);
-
- py_on_tx_begin = PyObject_GetAttrString(module, "on_tx_begin");
- if (py_on_tx_begin && PyCallable_Check(py_on_tx_begin))
- filter_api_on_tx_begin(on_tx_begin);
-
- py_on_tx_commit = PyObject_GetAttrString(module, "on_tx_commit");
- if (py_on_tx_commit && PyCallable_Check(py_on_tx_commit))
- filter_api_on_tx_commit(on_tx_commit);
-
- py_on_tx_rollback = PyObject_GetAttrString(module, "on_tx_rollback");
- if (py_on_tx_rollback && PyCallable_Check(py_on_tx_rollback))
- filter_api_on_tx_rollback(on_tx_rollback);
-
- py_on_dataline = PyObject_GetAttrString(module, "on_dataline");
- if (py_on_dataline && PyCallable_Check(py_on_dataline))
- filter_api_on_dataline(on_dataline);
-
- py_on_disconnect = PyObject_GetAttrString(module, "on_disconnect");
- if (py_on_disconnect && PyCallable_Check(py_on_disconnect))
- filter_api_on_disconnect(on_disconnect);
-
- filter_api_no_chroot();
- if (c)
- filter_api_set_chroot(c);
-
- filter_api_loop();
- log_debug("debug: exiting");
-
- Py_Finalize();
-
- return 1;
-}