⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rlm_python.c

📁 新的radius程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * rlm_python.c * * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or *   (at your option) any later version. * *   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * Copyright 2000  The FreeRADIUS server project * Copyright 2002  Miguel A.L. Paraz <mparaz@mparaz.com> * Copyright 2002  Imperium Technology, Inc. */#include <Python.h>#include "autoconf.h"#include "libradius.h"#include <stdio.h>#include <stdlib.h>#include "radiusd.h"#include "modules.h"#include "conffile.h"#define Pyx_BLOCK_THREADS       {PyGILState_STATE __gstate = PyGILState_Ensure();#define Pyx_UNBLOCK_THREADS     PyGILState_Release(__gstate);}static const char rcsid[] = "$Id: rlm_python.c,v 1.6.4.1 2007/03/05 14:15:28 pnixon Exp $";/* *	Define a structure for our module configuration. * *	These variables do not need to be in a structure, but it's *	a lot cleaner to do so, and a pointer to the structure can *	be used as the instance handle. */struct rlm_python_t {        char    *mod_instantiate;        char    *mod_authorize;        char    *mod_authenticate;        char    *mod_preacct;        char    *mod_accounting;        char    *mod_checksimul;        char    *mod_detach;        /* Names of functions */        char    *func_instantiate;        char    *func_authorize;        char    *func_authenticate;        char    *func_preacct;        char    *func_accounting;        char    *func_checksimul;        char    *func_detach;        PyObject *pModule_instantiate;        PyObject *pModule_authorize;        PyObject *pModule_authenticate;        PyObject *pModule_preacct;        PyObject *pModule_accounting;        PyObject *pModule_checksimul;        PyObject *pModule_detach;        /* Functions */        PyObject *pFunc_instantiate;        PyObject *pFunc_authorize;        PyObject *pFunc_authenticate;        PyObject *pFunc_preacct;        PyObject *pFunc_accounting;        PyObject *pFunc_checksimul;        PyObject *pFunc_detach;};/* *	A mapping of configuration file names to internal variables. * *	Note that the string is dynamically allocated, so it MUST *	be freed.  When the configuration file parse re-reads the string, *	it free's the old one, and strdup's the new one, placing the pointer *	to the strdup'd string into 'config.string'.  This gets around *	buffer over-flows. */static CONF_PARSER module_config[] = {  { "mod_instantiate",  PW_TYPE_STRING_PTR,    offsetof(struct rlm_python_t, mod_instantiate), NULL,  NULL},  { "func_instantiate",  PW_TYPE_STRING_PTR,    offsetof(struct rlm_python_t, func_instantiate), NULL,  NULL},  { "mod_authorize",  PW_TYPE_STRING_PTR,    offsetof(struct rlm_python_t, mod_authorize), NULL,  NULL},  { "func_authorize",  PW_TYPE_STRING_PTR,    offsetof(struct rlm_python_t, func_authorize), NULL,  NULL},  { "mod_authenticate",  PW_TYPE_STRING_PTR,    offsetof(struct rlm_python_t, mod_authenticate), NULL,  NULL},  { "func_authenticate",  PW_TYPE_STRING_PTR,    offsetof(struct rlm_python_t, func_authenticate), NULL,  NULL},  { "mod_preacct",  PW_TYPE_STRING_PTR,    offsetof(struct rlm_python_t, mod_preacct), NULL,  NULL},  { "func_preacct",  PW_TYPE_STRING_PTR,    offsetof(struct rlm_python_t, func_preacct), NULL,  NULL},  { "mod_accounting",  PW_TYPE_STRING_PTR,    offsetof(struct rlm_python_t, mod_accounting), NULL,  NULL},  { "func_accounting",  PW_TYPE_STRING_PTR,    offsetof(struct rlm_python_t, func_accounting), NULL,  NULL},  { "mod_checksimul",  PW_TYPE_STRING_PTR,    offsetof(struct rlm_python_t, mod_checksimul), NULL,  NULL},  { "func_checksimul",  PW_TYPE_STRING_PTR,    offsetof(struct rlm_python_t, func_checksimul), NULL,  NULL},  { "mod_detach",  PW_TYPE_STRING_PTR,    offsetof(struct rlm_python_t, mod_detach), NULL,  NULL},  { "func_detach",  PW_TYPE_STRING_PTR,    offsetof(struct rlm_python_t, func_detach), NULL,  NULL},  { NULL, -1, 0, NULL, NULL }		/* end the list */};static struct {        const char*     name;        int             value;} radiusd_constants[] = {        { "L_DBG",              L_DBG                   },        { "L_AUTH",             L_AUTH                  },        { "L_INFO",             L_INFO                  },        { "L_ERR",              L_ERR                   },        { "L_PROXY",            L_PROXY                 },        { "L_CONS",             L_CONS                  },        { "RLM_MODULE_REJECT",  RLM_MODULE_REJECT       },        { "RLM_MODULE_FAIL",    RLM_MODULE_FAIL         },        { "RLM_MODULE_OK",      RLM_MODULE_OK           },        { "RLM_MODULE_HANDLED", RLM_MODULE_HANDLED      },        { "RLM_MODULE_INVALID", RLM_MODULE_INVALID      },        { "RLM_MODULE_USERLOCK",RLM_MODULE_USERLOCK     },        { "RLM_MODULE_NOTFOUND",RLM_MODULE_NOTFOUND     },        { "RLM_MODULE_NOOP",    RLM_MODULE_NOOP         },        { "RLM_MODULE_UPDATED", RLM_MODULE_UPDATED      },        { "RLM_MODULE_NUMCODES",RLM_MODULE_NUMCODES     },        { NULL, 0 },};/* Let assume that radiusd module is only one since we have only one intepreter */static PyObject *radiusd_module = NULL;/* * radiusd Python functions *//* radlog wrapper */static PyObject *python_radlog(const PyObject *module, PyObject *args) {    int status;    char *msg;    if (!PyArg_ParseTuple(args, "is", &status, &msg)) {	return NULL;    }    radlog(status, "%s", msg);    Py_INCREF(Py_None);    return Py_None;}static PyMethodDef radiusd_methods[] = {    {"radlog", (PyCFunction) &python_radlog, METH_VARARGS, "freeradius radlog()."},    {NULL, NULL, 0, NULL}};static void python_error() {    PyObject        *pType = NULL;    PyObject        *pValue = NULL;    PyObject        *pTraceback = NULL;    PyObject        *pStr1 = NULL;    PyObject        *pStr2 = NULL;    Pyx_BLOCK_THREADS    PyErr_Fetch(&pType, &pValue, &pTraceback);    if (pType == NULL || pValue == NULL)        goto failed;    if ((pStr1 = PyObject_Str(pType)) == NULL || (pStr2 = PyObject_Str(pValue)) == NULL)        goto failed;    radlog(L_ERR, "rlm_python:EXCEPT:%s: %s", PyString_AsString(pStr1), PyString_AsString(pStr2));failed:    Py_XDECREF(pStr1);    Py_XDECREF(pStr2);    Py_XDECREF(pType);    Py_XDECREF(pValue);    Py_XDECREF(pTraceback);    Pyx_UNBLOCK_THREADS}static int python_init(){    int i;    Py_SetProgramName("radiusd");    Py_Initialize();    PyEval_InitThreads(); // This also grabs a lock    if ((radiusd_module = Py_InitModule3("radiusd", radiusd_methods, "FreeRADIUS Module.")) == NULL)        goto failed;    for (i = 0; radiusd_constants[i].name; i++)        if ((PyModule_AddIntConstant(radiusd_module, radiusd_constants[i].name, radiusd_constants[i].value)) < 0)            goto failed;    PyEval_ReleaseLock(); // Drop lock grabbed by InitThreads    radlog(L_DBG, "python_init done");    return 0;failed:    python_error();    Py_Finalize();    return -1;}static int python_destroy() {    Pyx_BLOCK_THREADS    Py_XDECREF(radiusd_module);    Py_Finalize();    Pyx_UNBLOCK_THREADS    return 0;}static void python_vptuple(VALUE_PAIR **vpp, PyObject *pValue, const char *funcname) {        int             i;        int             tuplesize;        VALUE_PAIR      *vp;        /* If the Python function gave us None for the tuple, then just return. */        if (pValue == Py_None)                return;        if (!PyTuple_CheckExact(pValue)) {                radlog(L_ERR, "rlm_python:%s: non-tuple passed", funcname);                return;        }        /* Get the tuple tuplesize. */        tuplesize = PyTuple_GET_SIZE(pValue);        for (i = 0; i < tuplesize; i++) {                PyObject *pTupleElement = PyTuple_GET_ITEM(pValue, i);                PyObject *pStr1;                PyObject *pStr2;                int pairsize;                const char *s1;                const char *s2;                if (!PyTuple_CheckExact(pTupleElement)) {                        radlog(L_ERR, "rlm_python:%s: tuple element %d is not a tuple", funcname, i);                        continue;                }                /* Check if it's a pair */                if ((pairsize = PyTuple_GET_SIZE(pTupleElement)) != 2) {                        radlog(L_ERR, "rlm_python:%s: tuple element %d is a tuple of size %d. Must be 2", funcname, i, pairsize);                        continue;                }                pStr1 = PyTuple_GET_ITEM(pTupleElement, 0);                pStr2 = PyTuple_GET_ITEM(pTupleElement, 1);                if ((!PyString_CheckExact(pStr1)) || (!PyString_CheckExact(pStr2))) {                        radlog(L_ERR, "rlm_python:%s: tuple element %d must be as (str, str)", funcname, i);                        continue;                }                s1 = PyString_AsString(pStr1);                s2 = PyString_AsString(pStr2);                /* xxx Might need to support other T_OP */                vp = pairmake(s1, s2, T_OP_EQ);                if (vp != NULL) {                        pairadd(vpp, vp);                        radlog(L_DBG, "rlm_python:%s: '%s' = '%s'", funcname, s1, s2);                } else {                        radlog(L_DBG, "rlm_python:%s: Failed: '%s' = '%s'", funcname, s1, s2);                }        }}/* This is the core Python function that the others wrap around. * Pass the value-pair print strings in a tuple. * xxx We're not checking the errors. If we have errors, what do we do? */static int python_function(REQUEST *request, PyObject *pFunc, const char *funcname) {        char            buf[1024];        VALUE_PAIR      *vp;        PyObject        *pRet = NULL;        PyObject        *pArgs = NULL;        int             tuplelen;        int             ret;	PyGILState_STATE gstate;        /* Return with "OK, continue" if the function is not defined. */        if (pFunc == NULL)                return RLM_MODULE_OK;        /* Default return value is "OK, continue" */        ret = RLM_MODULE_OK;        /* We will pass a tuple containing (name, value) tuples         * We can safely use the Python function to build up a tuple,         * since the tuple is not used elsewhere.         *         * Determine the size of our tuple by walking through the packet.         * If request is NULL, pass None.         */        tuplelen = 0;        if (request != NULL) {                for (vp = request->packet->vps; vp; vp = vp->next)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -