# HG changeset patch # User Sebastien Decugis # Date 1271300192 -32400 # Node ID cb4307a1cd29ed149caa2e0437deb77d98057818 # Parent a857024cb48ba87fe8da9f2aa4f9149ad51762b1 Added two plugins for RADIUS/Diameter gateway debug. diff -r a857024cb48b -r cb4307a1cd29 extensions/app_radgw/CMakeLists.txt --- a/extensions/app_radgw/CMakeLists.txt Wed Apr 14 18:30:22 2010 +0900 +++ b/extensions/app_radgw/CMakeLists.txt Thu Apr 15 11:56:32 2010 +0900 @@ -16,6 +16,8 @@ SET( RG_COMMON_SRC radius.c md5.c + rgw_msg_codes.c + rgw_msg_attrtype.c ) SET( RG_COMMON_HEADER rgw_common.h @@ -53,6 +55,28 @@ +########### RADIUS/Diameter translation agent plugins (support for RADIUS protocol) ############ +# Use the macro RGWX_ADD_PLUGIN(name files...) to create a plugin. +# It is equivalent to add_library with the appropriate parameters +# and naming conventions (.rgwx : Radius GateWay eXtension) +MACRO(RGWX_ADD_PLUGIN PLGNAME) + ADD_LIBRARY(${PLGNAME} MODULE ${ARGN}) + SET_TARGET_PROPERTIES(${PLGNAME} PROPERTIES PREFIX "" ) + SET_TARGET_PROPERTIES(${PLGNAME} PROPERTIES SUFFIX ".rgwx" ) + TARGET_LINK_LIBRARIES(${PLGNAME} rgw_common) +ENDMACRO(RGWX_ADD_PLUGIN) + +# Example of plugin: +OPTION(BUILD_RGWX_SAMPLE "Build sample plugin? (for developers only)" OFF) + IF (BUILD_RGWX_SAMPLE) + RGWX_ADD_PLUGIN(sample ${RG_COMMON_HEADER} rgwx_sample.c) + ENDIF (BUILD_RGWX_SAMPLE) + +# A plugin for debug: dumps RADIUS and Diameter messages state at the time the plugin is called. +OPTION(BUILD_RGWX_DEBUG "Build debug plugin? (display status of RADIUS and Diameter messages)" ON) + IF (BUILD_RGWX_DEBUG) + RGWX_ADD_PLUGIN(debug ${RG_COMMON_HEADER} rgwx_debug.c) + ENDIF (BUILD_RGWX_DEBUG) @@ -62,19 +86,7 @@ -########### Sub extensions ############# -# Example of support extension: -# OPTION(BUILD_RADIUS_GW_SAMPLE "Build sample sub-extension? (for debug only)" OFF) -# IF (BUILD_RADIUS_GW_SAMPLE) -# ADD_LIBRARY(sub_sample MODULE ${RG_COMMON_HEADER} sub_sample.c) -# TARGET_LINK_LIBRARIES(sub_sample rg_common) -# ENDIF (BUILD_RADIUS_GW_SAMPLE) - -# OPTION(BUILD_SUB_DEBUG "Build debug sub-extension? (display status of RADIUS and Diameter messages)" ON) -# IF (BUILD_SUB_DEBUG) -# ADD_LIBRARY(sub_debug MODULE ${RG_COMMON_HEADER} sub_debug.c) -# TARGET_LINK_LIBRARIES(sub_debug rg_common) -# ENDIF (BUILD_SUB_DEBUG) + # # OPTION(BUILD_SUB_ECHO_DROP "Build 'echo/drop' sub-extension? (echo or drop specific RADIUS attributes, no Diameter translation)" ON) # IF (BUILD_SUB_ECHO_DROP) diff -r a857024cb48b -r cb4307a1cd29 extensions/app_radgw/rgw_common.h --- a/extensions/app_radgw/rgw_common.h Wed Apr 14 18:30:22 2010 +0900 +++ b/extensions/app_radgw/rgw_common.h Thu Apr 15 11:56:32 2010 +0900 @@ -218,5 +218,8 @@ DIAM_ATTR_ACCOUNTING_EAP_AUTH_METHOD = 465 }; +const char * rgw_msg_attrtype_str(unsigned char c); +const char * rgw_msg_code_str(unsigned char c); + #endif /* _RGW_COMMON_H */ diff -r a857024cb48b -r cb4307a1cd29 extensions/app_radgw/rgw_msg.c --- a/extensions/app_radgw/rgw_msg.c Wed Apr 14 18:30:22 2010 +0900 +++ b/extensions/app_radgw/rgw_msg.c Thu Apr 15 11:56:32 2010 +0900 @@ -40,10 +40,6 @@ #include "rgw.h" -/* Directly include the code of the functions for dumping (generated from the IANA registries) */ -#include "rgw_msg_codes.c" -#include "rgw_msg_attrtype.c" - /* Destroy a message */ void rgw_msg_free(struct rgw_radius_msg_meta ** msg) { diff -r a857024cb48b -r cb4307a1cd29 extensions/app_radgw/rgw_msg_attrtype.c --- a/extensions/app_radgw/rgw_msg_attrtype.c Wed Apr 14 18:30:22 2010 +0900 +++ b/extensions/app_radgw/rgw_msg_attrtype.c Thu Apr 15 11:56:32 2010 +0900 @@ -1,3 +1,41 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2009, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ +#include "rgw_common.h" + +/* The content of this file was semi-automatically generated from the IANA registry. */ + /* Name of RADIUS attribute from its code */ const char * rgw_msg_attrtype_str(unsigned char c) { /* 1 User-Name */ diff -r a857024cb48b -r cb4307a1cd29 extensions/app_radgw/rgw_msg_codes.c --- a/extensions/app_radgw/rgw_msg_codes.c Wed Apr 14 18:30:22 2010 +0900 +++ b/extensions/app_radgw/rgw_msg_codes.c Thu Apr 15 11:56:32 2010 +0900 @@ -1,3 +1,41 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2009, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ +#include "rgw_common.h" + +/* The content of this file was semi-automatically generated from the IANA registry. */ + /* Name of RADIUS command from its command code */ const char * rgw_msg_code_str(unsigned char c) { /* 1 Access-Request [RFC2865] */ diff -r a857024cb48b -r cb4307a1cd29 extensions/app_radgw/rgw_plugins.c --- a/extensions/app_radgw/rgw_plugins.c Wed Apr 14 18:30:22 2010 +0900 +++ b/extensions/app_radgw/rgw_plugins.c Thu Apr 15 11:56:32 2010 +0900 @@ -219,6 +219,7 @@ fd_log_debug("An error occurred while parsing configuration file '%s' in plugin '%s', aborting...\n", new->conffile, new->plgname); goto error; } + TRACE_DEBUG(INFO, "RADIUS/Diameter gateway plugin '%s%s%s%s' initialized.", new->plgname, conffile ? " (" : "", conffile ? new->conffile : "", conffile ? ")" : ""); } /* Now sort the array (very simple algorithm, but this list is usually small) of command codes and save */ @@ -492,10 +493,12 @@ struct plg_descr * plg = (struct plg_descr *) plg_list.next; fd_list_unlink(&plg->chain); free(plg->conffile); + free(plg->cc); + if (plg->cs && plg->descriptor && plg->descriptor->rgwp_conf_free ) { + TRACE_DEBUG(INFO, "RADIUS/Diameter gateway plugin '%s' cleaning up...", plg->plgname); + (*plg->descriptor->rgwp_conf_free)(plg->cs); + } free(plg->plgname); - free(plg->cc); - if (plg->cs && plg->descriptor && plg->descriptor->rgwp_conf_free ) - (*plg->descriptor->rgwp_conf_free)(plg->cs); dlclose(plg->dlo); free(plg); } diff -r a857024cb48b -r cb4307a1cd29 extensions/app_radgw/rgwx_debug.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extensions/app_radgw/rgwx_debug.c Thu Apr 15 11:56:32 2010 +0900 @@ -0,0 +1,153 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2009, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* Debug plugin for app_radgw */ + +#include "rgw_common.h" + +struct rgwp_config { + char * confstring; +}; + +/* The function called at plugin initialization */ +static struct rgwp_config * debug_conf_parse ( char * conf_file ) +{ + struct rgwp_config * ret = NULL; + + TRACE_ENTRY("%p", conf_file); + + CHECK_MALLOC_DO( ret = malloc(sizeof(struct rgwp_config)), return NULL ); + + ret->confstring = conf_file; + + return ret; +} + +/* This function is called when the plugin is unloaded, to cleanup all the states */ +static void debug_conf_free(struct rgwp_config * cs) +{ + TRACE_ENTRY("%p", cs); + CHECK_PARAMS_DO( cs, ); + free(cs); + return; +} + +/* Function to display the content of a RADIUS message (more friendly way than radius_msg_dump) */ +static void debug_dump_radius(struct radius_msg *msg) +{ + unsigned char *auth; + size_t i; + + auth = &(msg->hdr->authenticator[0]); + fd_log_debug(" id : 0x%02hhx, code: %hhd (%s)\n", msg->hdr->identifier, msg->hdr->code, rgw_msg_code_str(msg->hdr->code)); + fd_log_debug(" auth: %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx\n", + auth[0], auth[1], auth[2], auth[3], + auth[4], auth[5], auth[6], auth[7]); + fd_log_debug(" %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx\n", + auth[8], auth[9], auth[10], auth[11], + auth[12], auth[13], auth[14], auth[15]); + for (i = 0; i < msg->attr_used; i++) { + struct radius_attr_hdr *attr = (struct radius_attr_hdr *)(msg->buf + msg->attr_pos[i]); + fd_log_debug(" - len:%3hhu, type:0x%02hhx (%s)\n", attr->length, attr->type, rgw_msg_attrtype_str(attr->type)); + /* If we need to dump the value, it's better to call directly radius_msg_dump instead... */ + } +} + +/* Function called when a new RADIUS message is being converted to Diameter */ +static int debug_rad_req( struct rgwp_config * cs, struct session * session, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli ) +{ + TRACE_ENTRY("%p %p %p %p %p %p", cs, session, rad_req, rad_ans, diam_fw, cli); + + fd_log_debug("------------- RADIUS/Diameter Request Debug%s%s%s -------------\n", cs->confstring ? " [" : "", cs->confstring ?: "", cs->confstring ? "]" : ""); + + if (!rad_req) { + fd_log_debug(" RADIUS request: NULL pointer\n"); + } else { + fd_log_debug(" RADIUS request (%p) DUMP:\n", rad_req); + debug_dump_radius(rad_req); + } + + if (!rad_ans || ! *rad_ans) { + fd_log_debug(" RADIUS answer: NULL pointer\n"); + } else { + fd_log_debug(" RADIUS answer (%p) DUMP:\n", *rad_ans); + debug_dump_radius(*rad_ans); + } + + if (!diam_fw || ! *diam_fw) { + fd_log_debug(" Diameter message: NULL pointer\n"); + } else { + fd_log_debug(" Diameter message (%p) DUMP:\n", *diam_fw); + fd_msg_dump_walk(0, *diam_fw); + } + + fd_log_debug("=========== Debug%s%s%s complete =============\n", cs->confstring ? " [" : "", cs->confstring ?: "", cs->confstring ? "]" : ""); + + return 0; +} + +/* This one, when Diameter answer is converted to RADIUS */ +static int debug_diam_ans( struct rgwp_config * cs, struct session * session, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli ) +{ + TRACE_ENTRY("%p %p %p %p %p", cs, session, diam_ans, rad_fw, cli); + + fd_log_debug("------------- RADIUS/Diameter Answer Debug%s%s%s -------------\n", cs->confstring ? " [" : "", cs->confstring ?: "", cs->confstring ? "]" : ""); + + if (!diam_ans || ! *diam_ans) { + fd_log_debug(" Diameter message: NULL pointer\n"); + } else { + fd_log_debug(" Diameter message (%p) DUMP:\n", *diam_ans); + fd_msg_dump_walk(0, *diam_ans); + } + + if (!rad_fw || ! *rad_fw) { + fd_log_debug(" RADIUS answer: NULL pointer\n"); + } else { + fd_log_debug(" RADIUS answer (%p) DUMP:\n", *rad_fw); + debug_dump_radius(*rad_fw); + } + + fd_log_debug("=========== Debug%s%s%s complete =============\n", cs->confstring ? " [" : "", cs->confstring ?: "", cs->confstring ? "]" : ""); + return 0; +} + + +/* The exported symbol */ +struct rgw_api rgwp_descriptor = { + debug_conf_parse, + debug_conf_free, + debug_rad_req, + debug_diam_ans +}; diff -r a857024cb48b -r cb4307a1cd29 extensions/app_radgw/rgwx_sample.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extensions/app_radgw/rgwx_sample.c Thu Apr 15 11:56:32 2010 +0900 @@ -0,0 +1,94 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2009, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ + +/* Sample radius/diameter gateway plugin, for developers to see the structure of a plugin. */ + +#include "rgw_common.h" + +/* The state of this extension */ +struct rgwp_config { + /* In a real extension, we would store the parsed configuration file, and the states of the extension */ + int state; +}; + +/* The function called at plugin initialization */ +static struct rgwp_config * sample_conf_parse ( char * conf_file ) +{ + struct rgwp_config * ret = NULL; + + TRACE_ENTRY("%p", conf_file); + + CHECK_MALLOC_DO( ret = malloc(sizeof(struct rgwp_config)), return NULL ); + + ret->state = 1; + + return ret; +} + +/* This function is called when the plugin is unloaded, to cleanup all the states */ +static void sample_conf_free(struct rgwp_config * cs) +{ + TRACE_ENTRY("%p", cs); + CHECK_PARAMS_DO( cs, ); + free(cs); + return; +} + +/* This function is called on incoming RADIUS messages. It should handle (some) RADIUS data and store into the Diameter message. */ +static int sample_rad_req( struct rgwp_config * cs, struct session * session, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli ) +{ + TRACE_ENTRY("%p %p %p %p %p %p", cs, session, rad_req, rad_ans, diam_fw, cli); + CHECK_PARAMS(cs); + TRACE_DEBUG(INFO, "RADIUS/Diameter Sample plugin received a new RADIUS message."); + return 0; +} + +/* This function is called when a Diameter answer is coming back. It should remove the AVPs and add the attributes in the RADIUS message. */ +static int sample_diam_ans( struct rgwp_config * cs, struct session * session, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli ) +{ + TRACE_ENTRY("%p %p %p %p %p", cs, session, diam_ans, rad_fw, cli); + CHECK_PARAMS(cs); + TRACE_DEBUG(INFO, "RADIUS/Diameter Sample plugin received a new Diameter answer."); + return 0; +} + + +/* Finally, we declare the structure that will be loaded by main RADIUS/Diameter gateway extension */ +struct rgw_api rgwp_descriptor = { + sample_conf_parse, + sample_conf_free, + sample_rad_req, + sample_diam_ans +};