diff options
Diffstat (limited to 'extras/filters/filter-python/filter_python.c')
-rw-r--r-- | extras/filters/filter-python/filter_python.c | 539 |
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; -} |