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

📄 mod_radius.c

📁 gnu 的radius服务器很好用的
💻 C
字号:
/* This is mod_radius.c -- a GNU Radius interface module for PHP   Copyright (C) 2004, Sergey Sinkovsky     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. */#include "php.h"#include "zend_ini.h"#include <radius/radius.h>ZEND_BEGIN_MODULE_GLOBALS(radius)	grad_list_t *resources;ZEND_END_MODULE_GLOBALS(radius)	#ifdef ZTS# define MRADG(v) TSRMG(radius_globals_id, zend_radius_globals *, v)#else# define MRADG(v) (radius_globals.v)#endif	ZEND_DECLARE_MODULE_GLOBALS(radius);typedef void (*mod_destroy_resource_t)(void *ptr);struct mod_resource {	void *ptr;	mod_destroy_resource_t destr;};static void	mod_register_resource(void *ptr, mod_destroy_resource_t destr){	struct mod_resource *mr;	if (!MRADG(resources))		MRADG(resources) = grad_list_create();	mr = malloc(sizeof(*mr));	if (!mr)		zend_error(E_ERROR, "Not enough memory");	mr->ptr = ptr;	mr->destr = destr;	grad_list_append(MRADG(resources), mr);}static intmod_res_cmp(const void *a, const void *b){	const struct mod_resource *ma = a;	const struct mod_resource *mb = b;	return ma->ptr != mb->ptr;}static voidmod_destroy_resource(void *ptr){	struct mod_resource *res = grad_list_remove(MRADG(resources), ptr,						    mod_res_cmp);	if (res) {		res->destr(res->ptr);		free(res);	}}static intmod_free_res(void *item, void *data){	struct mod_resource *res = item;	if (res) {		res->destr(res->ptr);		free(res);	}	return 0;}static voidmod_destroy_all_resources(){	grad_list_destroy(&MRADG(resources), mod_free_res, NULL);}		static voidmod_destroy_queue(void *ptr){	grad_client_destroy_queue((grad_server_queue_t *)ptr);}	ZEND_MINFO_FUNCTION(radauthmod);ZEND_MINIT_FUNCTION(radauthmod);ZEND_MSHUTDOWN_FUNCTION(radauthmod);ZEND_RSHUTDOWN_FUNCTION(radauthmod);ZEND_FUNCTION(radius_auth_user);ZEND_FUNCTION(radius_query);ZEND_FUNCTION(radius_set_debug);ZEND_FUNCTION(radius_clear_debug);ZEND_FUNCTION(radius_lookup_value);ZEND_FUNCTION(radius_attribute_type);static unsigned char radius_query_args_force_ref[]  = { 5, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_FORCE, BYREF_FORCE };/* compiled function list so Zend knows what's in this module */zend_function_entry radauthmod_functions[] = {	ZEND_FE(radius_auth_user, NULL)	ZEND_FE(radius_query, radius_query_args_force_ref)	ZEND_FE(radius_set_debug, NULL)	ZEND_FE(radius_clear_debug, NULL)	ZEND_FE(radius_lookup_value, NULL) 	ZEND_FE(radius_attribute_type, NULL)	{NULL, NULL, NULL}};zend_module_entry radauthmod_module_entry = {	STANDARD_MODULE_HEADER,	"RADIUS auth module",	radauthmod_functions,	ZEND_MINIT(radauthmod),	ZEND_MSHUTDOWN(radauthmod),	NULL,	ZEND_RSHUTDOWN(radauthmod),	ZEND_MINFO(radauthmod),	NO_VERSION_YET,	STANDARD_MODULE_PROPERTIES};ZEND_MINIT_FUNCTION(radauthmod){	REGISTER_LONG_CONSTANT("RT_ACCESS_REQUEST", RT_ACCESS_REQUEST,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("RT_ACCESS_ACCEPT", RT_ACCESS_ACCEPT,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("RT_ACCESS_REJECT", RT_ACCESS_REJECT,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("RT_ACCOUNTING_REQUEST",			       RT_ACCOUNTING_REQUEST,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("RT_ACCOUNTING_RESPONSE",			       RT_ACCOUNTING_RESPONSE,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("RT_ACCOUNTING_STATUS",			       RT_ACCOUNTING_STATUS,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("RT_PASSWORD_REQUEST", RT_PASSWORD_REQUEST,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("RT_PASSWORD_ACK", RT_PASSWORD_ACK,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("RT_PASSWORD_REJECT", RT_PASSWORD_REJECT,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("RT_ACCOUNTING_MESSAGE",			       RT_ACCOUNTING_MESSAGE,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("RT_ACCESS_CHALLENGE", RT_ACCESS_CHALLENGE,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("RT_STATUS_SERVER", RT_STATUS_SERVER,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("RT_STATUS_CLIENT", RT_STATUS_CLIENT,			       CONST_CS | CONST_PERSISTENT);	/* Not implemented in GNU Radius, but have place in radius.h */	REGISTER_LONG_CONSTANT("RT_ASCEND_TERMINATE_SESSION",			       RT_ASCEND_TERMINATE_SESSION,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("RT_ASCEND_EVENT_REQUEST",			       RT_ASCEND_EVENT_REQUEST,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("RT_ASCEND_EVENT_RESPONSE",			       RT_ASCEND_EVENT_RESPONSE,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("RT_ASCEND_ALLOCATE_IP",			       RT_ASCEND_ALLOCATE_IP,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("RT_ASCEND_RELEASE_IP",			       RT_ASCEND_RELEASE_IP,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("PORT_AUTH", GRAD_PORT_AUTH,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("PORT_ACCT", GRAD_PORT_ACCT,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("TYPE_INVALID", GRAD_TYPE_INVALID,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("TYPE_INTEGER", GRAD_TYPE_INTEGER,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("TYPE_IPADDR", GRAD_TYPE_IPADDR,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("TYPE_STRING", GRAD_TYPE_STRING,			       CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("TYPE_DATE", GRAD_TYPE_DATE,			       CONST_CS | CONST_PERSISTENT);		grad_path_init();	srand(time(NULL));	if (grad_dict_init())		zend_error(E_ERROR, "Can't read RADIUS dictionaries");	return SUCCESS;}ZEND_MSHUTDOWN_FUNCTION(radauthmod){	UNREGISTER_INI_ENTRIES();	/* deallocate the dictionary entries */	grad_dict_free();	grad_path_free();	return SUCCESS;}ZEND_RSHUTDOWN_FUNCTION(radauthmod){	mod_destroy_all_resources();}ZEND_MINFO_FUNCTION(radauthmod){	php_info_print_table_start();	php_info_print_table_header(2, "Function", "Support");	php_info_print_table_row(2, "Checking user", "Enabled");	php_info_print_table_row(2, "Passing additional parameters",				 "Enabled");	php_info_print_table_row(2, "Build ", __DATE__ "  " __TIME__);	php_info_print_table_end();}#if COMPILE_DL_FIRST_MODULEZEND_GET_MODULE(radauthmod)#endifstatic voidput_string(grad_avp_t ** plist, int attrnum, zval * data){	zval dcopy = *data;	zval_copy_ctor(&dcopy);	convert_to_string(&dcopy);	grad_avl_add_pair(plist,			  grad_avp_create_string(attrnum,						 Z_STRVAL(dcopy)));	zval_dtor(&dcopy);}static voidput_long(grad_avp_t ** plist, int attrnum, zval * data){	long longval;	grad_dict_value_t *val = grad_value_name_to_value(Z_STRVAL(*data),							  attrnum);	if (val)		longval = val->value;	else {		zval dcopy = *data;				zval_copy_ctor(&dcopy);		convert_to_long(&dcopy);		longval = Z_LVAL(dcopy);		zval_dtor(&dcopy);	}	grad_avl_add_pair(plist,			  grad_avp_create_integer(attrnum, longval));}static voidput_ipaddr(grad_avp_t ** plist, int attrnum, zval * data){	zval dcopy = *data;	zval_copy_ctor(&dcopy);	convert_to_string(&dcopy);	grad_avl_add_pair(plist,			  grad_avp_create_integer(attrnum,						  grad_ip_strtoip(Z_STRVAL								  (dcopy))));	zval_dtor(&dcopy);}static voidput_data(grad_avp_t ** plist, grad_dict_attr_t * attr, zval * data){	switch (attr->type) {	case GRAD_TYPE_STRING:		put_string(plist, attr->value, data);		break;			case GRAD_TYPE_INTEGER:		put_long(plist, attr->value, data);		break;			case GRAD_TYPE_IPADDR:		put_ipaddr(plist, attr->value, data);		break;	default:		zend_error(E_ERROR,			   "Unhadled data type for 3rd argument");	}}intconvert_pair_list(grad_avp_t ** plist, zval * obj){	zval          **data;	char           *key_str;	ulong           key_num;	int             i = 0;	if (obj != NULL) {		while (zend_hash_get_current_data(Z_ARRVAL(*obj),						  (void **) &data)		       == SUCCESS) {			grad_dict_attr_t *attr;			grad_avp_t     *pair;			key_str = NULL;			zend_hash_get_current_key(Z_ARRVAL(*obj),						  &key_str, &key_num,						  0);			if (key_str)				attr = grad_attr_name_to_dict(key_str);			else				attr = grad_attr_number_to_dict(key_num);			if (!attr) {				zend_error(E_ERROR, "Wrong 3rd parameter");			}			if (Z_TYPE_PP(data) == IS_ARRAY) {				zval          **data2;								while (zend_hash_get_current_data				       (Z_ARRVAL(**data),					(void **) &data2) == SUCCESS) {										put_data(plist, attr, *data2);					zend_hash_move_forward(Z_ARRVAL(**data));				}			} else				put_data(plist, attr, *data);			zend_hash_move_forward(Z_ARRVAL(*obj));		}	}}intconvert_from_pair_list(zval * obj, grad_avp_t * plist){	grad_avp_t     *p;	char            ipaddr[GRAD_IPV4_STRING_LENGTH];	if (array_init(obj) == FAILURE) {		zend_error(E_ERROR, "Can't initialize array");	}	for (p = plist; p; p = p->next) {		zval          **found;		if (zend_hash_find(Z_ARRVAL(*obj), p->name,				   strlen(p->name) + 1,				   (void **) &found) == SUCCESS) {			char           *str;			long            lval;						switch ((*found)->type) {			case IS_STRING:				str = Z_STRVAL(**found);				array_init(*found);				add_next_index_string(*found, str, 0);				break;			case IS_LONG:				lval = Z_LVAL(**found);				array_init(*found);				add_next_index_long(*found, lval);				break;			}			switch (p->type) {			case GRAD_TYPE_STRING:			case GRAD_TYPE_DATE:				add_next_index_string(*found, p->avp_strvalue,						      1);				break;			case GRAD_TYPE_INTEGER:			case GRAD_TYPE_IPADDR:				add_next_index_long(*found, p->avp_lvalue);				break;			}		} else			switch (p->type) {			case GRAD_TYPE_STRING:			case GRAD_TYPE_DATE:				add_assoc_string(obj, p->name, p->avp_strvalue,						 1);				break;							case GRAD_TYPE_INTEGER:			case GRAD_TYPE_IPADDR:				add_assoc_long(obj, p->name, p->avp_lvalue);				break;			}	}}char *get_reply_message(grad_avp_t * plist){	grad_avp_t     *p;	size_t          len;	char           *str, *s;	for (len = 0, p = plist; p; p = p->next)		if (p->attribute == DA_REPLY_MESSAGE)			len += p->avp_strlength;	str = emalloc(len + 1);		for (s = str, p = plist; p; p = p->next)		if (p->attribute == DA_REPLY_MESSAGE) {			strcpy(s, p->avp_strvalue);			s += strlen(s);		}		*s = 0;	return str;}ZEND_FUNCTION(radius_query){	int             port_type;	int             request_type;	zval           *pair_list = NULL;	zval           *reply_pairs = NULL;	zval           *reply_string = NULL;	int             reply_code;	grad_server_queue_t *queue;	grad_avp_t     *plist = NULL, *p;	grad_request_t *reply = NULL;		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,				  "lla|zz",				  &port_type,				  &request_type,				  &pair_list,				  &reply_pairs,				  &reply_string) == FAILURE) {		return;	}	if (reply_pairs && !PZVAL_IS_REF(reply_pairs)) {		zend_error(E_ERROR, "Argument 4 is not passed by reference");	}	if (reply_string && !PZVAL_IS_REF(reply_string)) {		zend_error(E_ERROR, "Argument 5 is not passed by reference");	}		queue = grad_client_create_queue(1, 0, 0);	mod_register_resource(queue, mod_destroy_queue);		convert_pair_list(&plist, pair_list);	reply = grad_client_send(queue, port_type, request_type, plist);		if (!reply) {		zend_error(E_ERROR, "No reply from servers");	}	reply_code = reply->code;	if (reply_string) {		ZVAL_STRING(reply_string, get_reply_message(reply->avlist),			    0);	}	if (reply_pairs) {		convert_from_pair_list(reply_pairs, reply->avlist);	}	grad_avl_free(plist);	grad_request_free(reply);	mod_destroy_resource(queue);		RETURN_LONG(reply_code);}ZEND_FUNCTION(radius_set_debug){	char           *levels;	int             levels_len;	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,				  "s",				  &levels,				  &levels_len) == FAILURE)		return;	grad_set_debug_levels(levels);}ZEND_FUNCTION(radius_clear_debug){	grad_clear_debug();}ZEND_FUNCTION(radius_lookup_value){	char           *attribute;	int             attribute_len;	char           *return_name;	grad_dict_value_t *vp;	int             value;	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,				  "sl",				  &attribute,				  &attribute_len,				  &value) == FAILURE)		return;	vp = grad_value_lookup(value, attribute);	if (!vp) {		  RETURN_NULL();	} 	RETURN_STRING(vp->name, 1);}ZEND_FUNCTION(radius_auth_user){	long            return_code;	char           *username;	int             username_len;	char           *password;	int             passwd_len;	zval           *pair_list = NULL;	grad_server_queue_t *queue;	grad_avp_t     *plist = NULL, *p;	grad_request_t *reply;	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,				  "ss|a",				  &username,				  &username_len,				  &password,				  &passwd_len,				  &pair_list) == FAILURE) {		return;	}        /* main auth proc */	queue = grad_client_create_queue(1, 0, 0);	mod_register_resource(queue, mod_destroy_queue);		/* 笙谀廖膳 有捎肆 辛

⌨️ 快捷键说明

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