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

📄 rlm_python.c

📁 freeradius-server-2.1.3.tar.gz安装源文件
💻 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * Copyright 2000,2006  The FreeRADIUS server project * Copyright 2002  Miguel A.L. Paraz <mparaz@mparaz.com> * Copyright 2002  Imperium Technology, Inc. * - rewritten by Paul P. Komkoff Jr <i@stingr.net> */#include <freeradius-devel/ident.h>RCSID("$Id$")#include <freeradius-devel/radiusd.h>#include <freeradius-devel/modules.h>#include <Python.h>#define Pyx_BLOCK_THREADS    {PyGILState_STATE __gstate = PyGILState_Ensure();#define Pyx_UNBLOCK_THREADS   PyGILState_Release(__gstate);}/* *	TODO: The only needed thing here is function. Anything else is *	required for initialization only. I will remove it, putting a *	symbolic constant here instead. */struct py_function_def {	PyObject *module;	PyObject *function;		char     *module_name;	char     *function_name;}; struct rlm_python_t {	struct py_function_def 		instantiate,		authorize,		authenticate,		preacct,		accounting,		checksimul,		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[] = {#define A(x) { "mod_" #x, PW_TYPE_STRING_PTR, offsetof(struct rlm_python_t, x.module_name), NULL, NULL }, \  { "func_" #x, PW_TYPE_STRING_PTR, offsetof(struct rlm_python_t, x.function_name), NULL, NULL },  A(instantiate)  A(authorize)  A(authenticate)  A(preacct)  A(accounting)  A(checksimul)  A(detach)#undef A  { NULL, -1, 0, NULL, NULL }		/* end the list */};static struct {  const char *name;  int  value;} radiusd_constants[] = {#define A(x) { #x, x },  A(L_DBG)  A(L_AUTH)  A(L_INFO)  A(L_ERR)  A(L_PROXY)  A(L_CONS)  A(RLM_MODULE_REJECT)  A(RLM_MODULE_FAIL)  A(RLM_MODULE_OK)  A(RLM_MODULE_HANDLED)  A(RLM_MODULE_INVALID)  A(RLM_MODULE_USERLOCK)  A(RLM_MODULE_NOTFOUND)  A(RLM_MODULE_NOOP)  A(RLM_MODULE_UPDATED)  A(RLM_MODULE_NUMCODES)#undef A  { 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(UNUSED 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", &python_radlog, METH_VARARGS, 	  "radiusd.radlog(level, msg)\n\n" \	  "Print a message using radiusd logging system. level should be one of the\n" \	  "constants L_DBG, L_AUTH, L_INFO, L_ERR, L_PROXY, L_CONS\n"	},	{ NULL, NULL, 0, NULL },};static void python_error(void){	PyObject 		*pType = NULL,		*pValue = NULL,		*pTraceback = NULL,		*pStr1 = NULL,		*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(void){	int i;	if (radiusd_module) return 0;		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_XDECREF(radiusd_module);	radiusd_module = NULL;	Py_Finalize();	return -1;}#if 0static int python_destroy(void){	Pyx_BLOCK_THREADS	Py_XDECREF(radiusd_module);	Py_Finalize();	Pyx_UNBLOCK_THREADS	return 0;}/* *	This will need reconsidering in a future. Maybe we'll need to *	have our own reference counting for radiusd_module */#endif/* TODO: Convert this function to accept any iterable objects? */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. * *	FIXME: We're not checking the errors. If we have errors, what *	do we do? */static int python_populate_vptuple(PyObject *pPair, VALUE_PAIR *vp){	PyObject *pStr = NULL;	char buf[1024];		/* Look at the vp_print_name? */		if (vp->flags.has_tag)		pStr = PyString_FromFormat("%s:%d", vp->name, vp->flags.tag);	else		pStr = PyString_FromString(vp->name);		if (pStr == NULL)		goto failed;		PyTuple_SET_ITEM(pPair, 0, pStr);		vp_prints_value(buf, sizeof(buf), vp, 1);		if ((pStr = PyString_FromString(buf)) == NULL)		goto failed;	PyTuple_SET_ITEM(pPair, 1, pStr);		return 0;	 failed:	return -1;}static int python_function(REQUEST *request, PyObject *pFunc,			   const char *funcname)

⌨️ 快捷键说明

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