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

📄 rlm_python.c

📁 free radius编程。完成AAA的实现
💻 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"static const char rcsid[] = "$Id: rlm_python.c,v 1.6 2004/02/26 19:04:34 aland 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. */typedef struct rlm_python_t {    /* Config section */    /* Names of modules */    char        *mod_instantiate,        *mod_authorize,	*mod_authenticate,	*mod_preacct,	*mod_accounting,	*mod_checksimul,	*mod_detach,    /* Names of functions */        *func_instantiate,        *func_authorize,	*func_authenticate,	*func_preacct,	*func_accounting,	*func_checksimul,	*func_detach;    /* End Config section */    /* Python objects for modules */    PyObject        *pModule_builtin,        *pModule_instantiate,        *pModule_authorize,	*pModule_authenticate,	*pModule_preacct,	*pModule_accounting,	*pModule_checksimul,	*pModule_detach,	/* Functions */	*pFunc_instantiate,	*pFunc_authorize,	*pFunc_authenticate,	*pFunc_preacct,	*pFunc_accounting,	*pFunc_checksimul,	*pFunc_detach;} rlm_python_t;/* *	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(rlm_python_t, mod_instantiate), NULL,  NULL},  { "func_instantiate",  PW_TYPE_STRING_PTR,    offsetof(rlm_python_t, func_instantiate), NULL,  NULL},  { "mod_authorize",  PW_TYPE_STRING_PTR,    offsetof(rlm_python_t, mod_authorize), NULL,  NULL},  { "func_authorize",  PW_TYPE_STRING_PTR,    offsetof(rlm_python_t, func_authorize), NULL,  NULL},  { "mod_authenticate",  PW_TYPE_STRING_PTR,    offsetof(rlm_python_t, mod_authenticate), NULL,  NULL},  { "func_authenticate",  PW_TYPE_STRING_PTR,    offsetof(rlm_python_t, func_authenticate), NULL,  NULL},  { "mod_preacct",  PW_TYPE_STRING_PTR,    offsetof(rlm_python_t, mod_preacct), NULL,  NULL},  { "func_preacct",  PW_TYPE_STRING_PTR,    offsetof(rlm_python_t, func_preacct), NULL,  NULL},  { "mod_accounting",  PW_TYPE_STRING_PTR,    offsetof(rlm_python_t, mod_accounting), NULL,  NULL},  { "func_accounting",  PW_TYPE_STRING_PTR,    offsetof(rlm_python_t, func_accounting), NULL,  NULL},  { "mod_checksimul",  PW_TYPE_STRING_PTR,    offsetof(rlm_python_t, mod_checksimul), NULL,  NULL},  { "func_checksimul",  PW_TYPE_STRING_PTR,    offsetof(rlm_python_t, func_checksimul), NULL,  NULL},  { "mod_detach",  PW_TYPE_STRING_PTR,    offsetof(rlm_python_t, mod_detach), NULL,  NULL},  { "func_detach",  PW_TYPE_STRING_PTR,    offsetof(rlm_python_t, func_detach), NULL,  NULL},  { NULL, -1, 0, NULL, NULL }		/* end the list */};/* * radiusd Python functions *//* radlog wrapper */static PyObject *radlog_py(const PyObject *self, PyObject *args) {    int status;    char *msg;    if (!PyArg_ParseTuple(args, "is", &status, &msg)) {	return NULL;    }    radlog(status, msg);    return Py_None;}static PyMethodDef radiusd_methods[] = {    {"radlog", (PyCFunction)radlog_py, METH_VARARGS, "freeradius radlog()."},    {NULL, NULL, 0, NULL}};/* *	Do any per-module initialization.  e.g. set up connections *	to external databases, read configuration files, set up *	dictionary entries, etc. * *	Try to avoid putting too much stuff in here - it's better to *	do it in instantiate() where it is not global. */static int python_init(void){    /*     * Initialize Python interpreter. Fatal error if this fails.     */    Py_Initialize();    radlog(L_DBG, "python_init done");    return 0;}/* Extract string representation of Python error. */static void python_error(void) {    PyObject *pType, *pValue, *pTraceback, *pStr1, *pStr2;    PyErr_Fetch(&pType, &pValue, &pTraceback);    pStr1 = PyObject_Str(pType);    pStr2 = PyObject_Str(pValue);    radlog(L_ERR, "%s: %s\n",	   PyString_AsString(pStr1), PyString_AsString(pStr2));}/* Tuple to value pair conversion */static void add_vp_tuple(VALUE_PAIR **vpp, PyObject *pValue,			 const char *function_name) {    int i, outertuplesize;    VALUE_PAIR	*vp;    /* If the Python function gave us None for the tuple, then just return. */    if (pValue == Py_None) {	return;    }    if (!PyTuple_Check(pValue)) {	radlog(L_ERR, "%s: non-tuple passed", function_name);    }    /* Get the tuple size. */    outertuplesize = PyTuple_Size(pValue);    for (i = 0; i < outertuplesize; i++) {	PyObject *pTupleElement = PyTuple_GetItem(pValue, i);	if ((pTupleElement != NULL) &&	    (PyTuple_Check(pTupleElement))) {	    /* Check if it's a pair */	    int tuplesize;	    if ((tuplesize = PyTuple_Size(pTupleElement)) != 2) {		radlog(L_ERR, "%s: tuple element %d is a tuple "		       " of size %d. must be 2\n", function_name,		       i, tuplesize);	    }	    else {		PyObject *pString1, *pString2;		pString1 = PyTuple_GetItem(pTupleElement, 0);		pString2 = PyTuple_GetItem(pTupleElement, 1);		/* xxx PyString_Check does not compile here */		if  ((pString1 != NULL) &&		     (pString2 != NULL) &&		     PyObject_TypeCheck(pString1,&PyString_Type) &&		     PyObject_TypeCheck(pString2,&PyString_Type)) {		    const char *s1, *s2;		    /* pairmake() will convert and find any		     * errors in the pair.		     */		    s1 = PyString_AsString(pString1);		    s2 = PyString_AsString(pString2);		    if ((s1 != NULL) && (s2 != NULL)) {			radlog(L_DBG, "%s: %s = %s ",			       function_name, s1, s2);			/* xxx Might need to support other T_OP */			vp = pairmake(s1, s2, T_OP_EQ);			if (vp != NULL) {			    pairadd(vpp, vp);			    radlog(L_DBG, "%s: s1, s2 OK\n",				   function_name);			}			else {			    radlog(L_DBG, "%s: s1, s2 FAILED\n",				   function_name);			}		    }		    else {			radlog(L_ERR, "%s: string conv failed\n",			       function_name);		    }		}		else {		    radlog(L_ERR, "%s: tuple element %d must be "			   "(string, string)", function_name, i);		}	    }	}	else {	    radlog(L_ERR, "%s: tuple element %d is not a tuple\n",		   function_name, i);	}    }}/* 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 *function_name){#define BUF_SIZE 1024    char buf[BUF_SIZE];		/* same size as vp_print buffer */    VALUE_PAIR	*vp;    PyObject *pValue, *pValuePairContainer, **pValueHolder, **pValueHolderPtr;    int i, n_tuple, return_value;    /* Return with "OK, continue" if the function is not defined. */    if (pFunc == NULL) {	return RLM_MODULE_OK;    }    /* Default return value is "OK, continue" */    return_value = 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.     */    n_tuple = 0;    if (request != NULL) {	for (vp = request->packet->vps; vp; vp = vp->next) {	    n_tuple++;	}    }    /* Create the tuple and a holder for the pointers, so that we can     * decref more efficiently later without the overhead of reading     * the tuple.     *     * We use malloc() instead of the Python memory allocator since we     * are not embedded.     */    if (NULL == (pValueHolder = pValueHolderPtr =		 malloc(sizeof(PyObject *) * n_tuple))) {	radlog(L_ERR, "%s: malloc of %d bytes failed\n",	       function_name, sizeof(PyObject *) * n_tuple);	return -1;    }    if (n_tuple == 0) {	pValuePairContainer = Py_None;    }    else {	pValuePairContainer = PyTuple_New(n_tuple);	i = 0;	for (vp = request->packet->vps; vp; vp = vp->next) {	    PyObject *pValuePair, *pString1, *pString2;	    /* The inside tuple has two only: */	    pValuePair = PyTuple_New(2);	    /* The name. logic from vp_prints, lib/print.c */	    if (vp->flags.has_tag) {		snprintf(buf, BUF_SIZE, "%s:%d", vp->name, vp->flags.tag);	    }	    else {		strcpy(buf, vp->name);	    }	    pString1 = PyString_FromString(buf);	    PyTuple_SetItem(pValuePair, 0, pString1);	    /* The value. Use delimiter - don't know what that means */	    vp_prints_value(buf, sizeof(buf), vp, 1);	    pString2 = PyString_FromString(buf);	    PyTuple_SetItem(pValuePair, 1, pString2);	    /* Put the tuple inside the container */	    PyTuple_SetItem(pValuePairContainer, i++, pValuePair);	    /* Store the pointer in our malloc() storage */	    *pValueHolderPtr++ = pValuePair;	}    }    /* Call Python function.     */    if (pFunc && PyCallable_Check(pFunc)) {	PyObject *pArgs;	/* call the function with a singleton tuple containing the	 * container tuple.	 */	if ((pArgs = PyTuple_New(1)) == NULL) {	    radlog(L_ERR, "%s: could not create tuple", function_name);	    return -1;

⌨️ 快捷键说明

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