changeset 550:4c935aecee6c

Hide and automate the Proxy-State attributes management in RADIUS gateway
author Sebastien Decugis <sdecugis@nict.go.jp>
date Wed, 15 Sep 2010 14:24:45 +0900
parents 1b8809c7d7cc
children 27f833e7f9c4
files doc/echodrop.rgwx.conf.sample extensions/app_radgw/radius.c extensions/app_radgw/radius.h extensions/app_radgw/rgw.h extensions/app_radgw/rgw_clients.c extensions/app_radgw/rgw_msg.c
diffstat 6 files changed, 226 insertions(+), 207 deletions(-) [+]
line wrap: on
line diff
--- a/doc/echodrop.rgwx.conf.sample	Wed Sep 15 10:44:46 2010 +0900
+++ b/doc/echodrop.rgwx.conf.sample	Wed Sep 15 14:24:45 2010 +0900
@@ -25,10 +25,9 @@
 #               and we match only this "Ext-Type" value (16 bits).
 #              This option should only be used with "CODE 26 VENDOR 0".
 #		
+# Note that the Proxy-State (code 33) attribute is handled directly as an ECHO parameter by the gateway core.
 
 # Examples:
 # DROP code 18 ; # Reply-Message attribute, should not be included in requests
 # DROP code 26 vendor 9 ; # Drop any Cisco-specific attribute
 # ECHO code 26 vendor 0 ext 256 ; # Echo any extended attribute with the type 256.
-
-ECHO code 33 ; # RADIUS Proxy-State attribute
--- a/extensions/app_radgw/radius.c	Wed Sep 15 10:44:46 2010 +0900
+++ b/extensions/app_radgw/radius.c	Wed Sep 15 14:24:45 2010 +0900
@@ -1,18 +1,44 @@
-/*********************************************************************************/
+/*********************************************************************************************************
+* Software License Agreement (BSD License)                                                               *
+* Author: Sebastien Decugis <sdecugis@nict.go.jp>							 *
+*													 *
+* Copyright (c) 2010, 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.								 *
+*********************************************************************************************************/
+
 /* freeDiameter author note:
- *  The content from this file comes directly from the hostap project.
+ *  The content from this file comes for the main part from the hostap project.
  * It is redistributed under the terms of the BSD license, as allowed
  * by the original copyright reproduced bellow.
- *  In addition to this notice, the following changes have been done:
- *   - created the radius_msg_dump_attr_val function
+ * The modifications to this file are placed under the copyright of the freeDiameter project.
  */
-#include "rgw_common.h"
-
-/* Overwrite printf */
-#define printf(args...) fd_log_debug(args)
-
-/*********************************************************************************/
-
 
 /*
  * hostapd / RADIUS message processing
@@ -28,6 +54,13 @@
  * See README and COPYING for more details.
  */
 
+/*********************************************************************************/
+#include "rgw.h"
+
+/* Overwrite printf */
+#define printf(args...) fd_log_debug(args)
+
+
 static struct radius_attr_hdr *
 radius_get_attr_hdr(struct radius_msg *msg, int idx)
 {
@@ -103,24 +136,19 @@
 	msg->attr_size = msg->attr_used = 0;
 }
 
-
-static const char *radius_code_string(u8 code)
+/* Destroy a message */
+void rgw_msg_free(struct rgw_radius_msg_meta ** msg)
 {
-	switch (code) {
-	case RADIUS_CODE_ACCESS_REQUEST: return "Access-Request";
-	case RADIUS_CODE_ACCESS_ACCEPT: return "Access-Accept";
-	case RADIUS_CODE_ACCESS_REJECT: return "Access-Reject";
-	case RADIUS_CODE_ACCOUNTING_REQUEST: return "Accounting-Request";
-	case RADIUS_CODE_ACCOUNTING_RESPONSE: return "Accounting-Response";
-	case RADIUS_CODE_ACCESS_CHALLENGE: return "Access-Challenge";
-	case RADIUS_CODE_STATUS_SERVER: return "Status-Server";
-	case RADIUS_CODE_STATUS_CLIENT: return "Status-Client";
-	case RADIUS_CODE_RESERVED: return "Reserved";
-	default: return "?Unknown?";
-	}
+	if (!msg || !*msg)
+		return;
+	
+	radius_msg_free(&(*msg)->radius);
+	free(*msg);
+	*msg = NULL;
 }
 
 
+
 struct radius_attr_type {
 	u8 type;
 	char *name;
@@ -218,7 +246,7 @@
 }
 
 
-void radius_msg_dump_attr_val(struct radius_attr_hdr *hdr)
+static void radius_msg_dump_attr_val(struct radius_attr_hdr *hdr)
 {
 	struct radius_attr_type *attr;
 	int i, len;
@@ -281,31 +309,36 @@
 	}
 }
 
-static void radius_msg_dump_attr(struct radius_attr_hdr *hdr)
+/* Dump a message  -- can be used safely with a struct radius_msg as parameter (we don't dump the metadata) */
+void rgw_msg_dump(struct rgw_radius_msg_meta * msg)
 {
-	struct radius_attr_type *attr;
-
-	attr = radius_get_attr_type(hdr->type);
-
-	printf("   Attribute %d (%s) length=%d\n",
-	       hdr->type, attr ? attr->name : "?Unknown?", hdr->length);
+	unsigned char *auth;
+	size_t i;
+	if (! TRACE_BOOL(FULL) )
+		return;
+	
+	auth =  &(msg->radius.hdr->authenticator[0]);
 	
-	radius_msg_dump_attr_val(hdr);
-}
-
-
-void radius_msg_dump(struct radius_msg *msg)
-{
-	size_t i;
-
-	printf("RADIUS message: code=%d (%s) identifier=%d length=%d\n",
-	       msg->hdr->code, radius_code_string(msg->hdr->code),
-	       msg->hdr->identifier, ntohs(msg->hdr->length));
-
-	for (i = 0; i < msg->attr_used; i++) {
-		struct radius_attr_hdr *attr = radius_get_attr_hdr(msg, i);
-		radius_msg_dump_attr(attr);
+	fd_log_debug("------ RADIUS msg dump -------\n");
+	fd_log_debug(" id  : 0x%02hhx, code : %hhd (%s), length : %d\n", msg->radius.hdr->identifier, msg->radius.hdr->code, rgw_msg_code_str(msg->radius.hdr->code), ntohs(msg->radius.hdr->length));
+	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->radius.attr_used; i++) {
+		struct radius_attr_hdr *attr = (struct radius_attr_hdr *)(msg->radius.buf + msg->radius.attr_pos[i]);
+		fd_log_debug("    - Type: 0x%02hhx (%s)\n       Len: %-3hhu", attr->type, rgw_msg_attrtype_str(attr->type), attr->length);
+		radius_msg_dump_attr_val(attr);
 	}
+	if (msg->ps_nb) {
+		fd_log_debug("---- hidden attributes:\n");
+		for (i = msg->ps_first; i < msg->ps_first + msg->ps_nb; i++) {
+			struct radius_attr_hdr *attr = (struct radius_attr_hdr *)(msg->radius.buf + msg->radius.attr_pos[i]);
+			fd_log_debug("    - Type: 0x%02hhx (%s)\n       Len: %-3hhu", attr->type, rgw_msg_attrtype_str(attr->type), attr->length);
+			radius_msg_dump_attr_val(attr);
+		}
+	}
+	fd_log_debug("-----------------------------\n");
 }
 
 
@@ -406,7 +439,7 @@
 }
 
 
-static int radius_msg_add_attr_to_array(struct radius_msg *msg,
+int radius_msg_add_attr_to_array(struct radius_msg *msg,
 					struct radius_attr_hdr *attr)
 {
 	if (msg->attr_used >= msg->attr_size) {
@@ -473,69 +506,114 @@
 }
 
 
-struct radius_msg *radius_msg_parse(const u8 *data, size_t len)
+/* Modified version of radius_msg_parse */
+int rgw_msg_parse(unsigned char * buf, size_t len, struct rgw_radius_msg_meta ** msg)
 {
-	struct radius_msg *msg;
+	struct rgw_radius_msg_meta * temp_msg = NULL;
 	struct radius_hdr *hdr;
 	struct radius_attr_hdr *attr;
 	size_t msg_len;
 	unsigned char *pos, *end;
-
-	if (data == NULL || len < sizeof(*hdr))
-		return NULL;
-
-	hdr = (struct radius_hdr *) data;
-
+	int ret = 0;
+	
+	TRACE_ENTRY("%p %g %p", buf, len, msg);
+	
+	CHECK_PARAMS( buf && len >= sizeof(*hdr) && msg );
+	
+	*msg = NULL;
+	
+	/* Parse the RADIUS message */
+	hdr = (struct radius_hdr *) buf;
 	msg_len = ntohs(hdr->length);
 	if (msg_len < sizeof(*hdr) || msg_len > len) {
-		printf("Invalid RADIUS message length\n");
-		return NULL;
+		TRACE_DEBUG(INFO, "Invalid RADIUS message length\n");
+		return EINVAL;
 	}
 
 	if (msg_len < len) {
-		printf("Ignored %lu extra bytes after RADIUS message\n",
+		TRACE_DEBUG(INFO, "Ignored %lu extra bytes after RADIUS message\n",
 		       (unsigned long) len - msg_len);
 	}
 
-	msg = os_malloc(sizeof(*msg));
-	if (msg == NULL)
-		return NULL;
-
-	if (radius_msg_initialize(msg, msg_len)) {
-		os_free(msg);
-		return NULL;
+	CHECK_MALLOC( temp_msg = malloc(sizeof(struct rgw_radius_msg_meta)) );
+	memset(temp_msg, 0, sizeof(struct rgw_radius_msg_meta));
+	
+	if (radius_msg_initialize(&temp_msg->radius, msg_len)) {
+		TRACE_DEBUG(INFO, "Error in radius_msg_initialize, returning ENOMEM.");
+		free(temp_msg);
+		return ENOMEM;
 	}
-
-	os_memcpy(msg->buf, data, msg_len);
-	msg->buf_size = msg->buf_used = msg_len;
-
+	
+	/* Store the received data in the alloc'd buffer */
+	memcpy(temp_msg->radius.buf, buf, msg_len);
+	temp_msg->radius.buf_size = temp_msg->radius.buf_used = msg_len;
+	
 	/* parse attributes */
-	pos = (unsigned char *) (msg->hdr + 1);
-	end = msg->buf + msg->buf_used;
+	pos = (unsigned char *) (temp_msg->radius.hdr + 1);
+	end = temp_msg->radius.buf + temp_msg->radius.buf_used;
+	
 	while (pos < end) {
-		if ((size_t) (end - pos) < sizeof(*attr))
-			goto fail;
-
+		if ((size_t) (end - pos) < sizeof(*attr)) {
+			TRACE_DEBUG(INFO, "Trucated attribute found in RADIUS buffer, EINVAL.");
+			ret = EINVAL;
+			break;
+		}
+			
 		attr = (struct radius_attr_hdr *) pos;
+	
+		if (pos + attr->length > end || attr->length < sizeof(*attr)) {
+			TRACE_DEBUG(INFO, "Trucated attribute found in RADIUS buffer, EINVAL.");
+			ret = EINVAL;
+			break;
+		}
 
-		if (pos + attr->length > end || attr->length < sizeof(*attr))
-			goto fail;
-
-		/* TODO: check that attr->length is suitable for attr->type */
-
-		if (radius_msg_add_attr_to_array(msg, attr))
-			goto fail;
+		if (radius_msg_add_attr_to_array(&temp_msg->radius, attr)) {
+			TRACE_DEBUG(INFO, "Error in radius_msg_add_attr_to_array, ENOMEM");
+			ret = ENOMEM;
+			break;
+		}
+		
+		if (attr->type == RADIUS_ATTR_PROXY_STATE)
+			temp_msg->ps_nb += 1;
 
 		pos += attr->length;
 	}
-
-	return msg;
+	
+	if (ret != 0) {
+		radius_msg_free(&temp_msg->radius);
+		free(temp_msg);
+		return ret;
+	}
+	
+	/* Now move all the proxy-state attributes at the end of the attr_pos array */
+	if (temp_msg->ps_nb) {
+		size_t *temp_ps = NULL;
+		int n, new_n = 0, p = 0;
+		
+		CHECK_MALLOC( temp_ps = calloc(temp_msg->ps_nb, sizeof(size_t *)) );
+		
+		/* Move all the Proxy-State attributes into the temp_ps array */
+		for (n=0; n < temp_msg->radius.attr_used; n++) {
+			struct radius_attr_hdr * attr = (struct radius_attr_hdr *)(temp_msg->radius.buf + temp_msg->radius.attr_pos[n]);
+			
+			if (attr->type == RADIUS_ATTR_PROXY_STATE) {
+				temp_ps[p++] = temp_msg->radius.attr_pos[n];
+			} else {
+				temp_msg->radius.attr_pos[new_n++] = temp_msg->radius.attr_pos[n];
+			}
+		}
+		temp_msg->radius.attr_used = new_n; /* hide the proxy-state to other modules */
+		temp_msg->ps_first = new_n;
+		
+		/* And back into the array */
+		memcpy(temp_msg->radius.attr_pos + new_n, temp_ps, p * sizeof(size_t *));
+		free(temp_ps);
+	}
+	
+	*msg = temp_msg;
+	return 0;
+}
 
- fail:
-	radius_msg_free(msg);
-	os_free(msg);
-	return NULL;
-}
 
 
 int radius_msg_add_eap(struct radius_msg *msg, const u8 *data, size_t data_len)
--- a/extensions/app_radgw/radius.h	Wed Sep 15 10:44:46 2010 +0900
+++ b/extensions/app_radgw/radius.h	Wed Sep 15 14:24:45 2010 +0900
@@ -1,15 +1,46 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License)                                                               *
+* Author: Sebastien Decugis <sdecugis@nict.go.jp>							 *
+*													 *
+* Copyright (c) 2010, 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.								 *
+*********************************************************************************************************/
+
 /*********************************************************************************/
 /* freeDiameter author note:
- *  The content from this file comes directly from the hostap project.
+ *  The content from this file comes mostly from the hostap project.
  * It is redistributed under the terms of the BSD license, as allowed
  * by the original copyright reproduced bellow.
- *  The file has not been modified, except for this notice and
- * declaration of:
- *  void radius_msg_dump_attr_val(struct radius_attr_hdr *hdr);
+ * The changes to this file are placed under the copyright of the freeDiameter project.
  */
 
-/*********************************************************************************/
-
 /*
  * hostapd / RADIUS message processing
  * Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
@@ -23,6 +54,8 @@
  *
  * See README and COPYING for more details.
  */
+/*********************************************************************************/
+
 
 #ifndef RADIUS_H
 #define RADIUS_H
@@ -218,8 +251,6 @@
 int radius_msg_initialize(struct radius_msg *msg, size_t init_len);
 void radius_msg_set_hdr(struct radius_msg *msg, u8 code, u8 identifier);
 void radius_msg_free(struct radius_msg *msg);
-void radius_msg_dump_attr_val(struct radius_attr_hdr *hdr);
-void radius_msg_dump(struct radius_msg *msg);
 int radius_msg_finish(struct radius_msg *msg, const u8 *secret,
 		      size_t secret_len);
 int radius_msg_finish_srv(struct radius_msg *msg, const u8 *secret,
@@ -228,7 +259,6 @@
 			    size_t secret_len);
 struct radius_attr_hdr *radius_msg_add_attr(struct radius_msg *msg, u8 type,
 					    const u8 *data, size_t data_len);
-struct radius_msg *radius_msg_parse(const u8 *data, size_t len);
 int radius_msg_add_eap(struct radius_msg *msg, const u8 *data,
 		       size_t data_len);
 u8 *radius_msg_get_eap(struct radius_msg *msg, size_t *len);
@@ -266,6 +296,7 @@
 	return radius_msg_add_attr(msg, type, (u8 *) &val, 4) != NULL;
 }
 
+int radius_msg_add_attr_to_array(struct radius_msg *msg, struct radius_attr_hdr *attr);
 static inline int radius_msg_get_attr_int32(struct radius_msg *msg, u8 type,
 					    u32 *value)
 {
--- a/extensions/app_radgw/rgw.h	Wed Sep 15 10:44:46 2010 +0900
+++ b/extensions/app_radgw/rgw.h	Wed Sep 15 14:24:45 2010 +0900
@@ -59,6 +59,9 @@
 		unsigned	valid_mac :1;
 	};
 	
+	/* For Proxy-State attributes: */
+	int	ps_first;	/* The index of the first Proxy-State attribute in radius.attr_pos. It is always >= radius.attr_used */
+	int	ps_nb;		/* The number of Proxy-State attributes. The real radius.attr_pos size is attr_used + ps_nb */
 };
 void rgw_msg_free(struct rgw_radius_msg_meta ** msg);
 int rgw_msg_parse(unsigned char * buf, size_t len, struct rgw_radius_msg_meta ** msg);
--- a/extensions/app_radgw/rgw_clients.c	Wed Sep 15 10:44:46 2010 +0900
+++ b/extensions/app_radgw/rgw_clients.c	Wed Sep 15 14:24:45 2010 +0900
@@ -974,6 +974,20 @@
 		return ENOTSUP;
 	}
 	
+	/* Add all the Proxy-States back in the message */
+	for (p = 0; p < req->ps_nb; p++) {
+		struct radius_attr_hdr * attr = (struct radius_attr_hdr *)(req->radius.buf + req->radius.attr_pos[req->ps_first + p]);
+		
+		if (radius_msg_add_attr_to_array(*msg, attr)) {
+			TRACE_DEBUG(INFO, "Error in radius_msg_add_attr_to_array, ENOMEM");
+			radius_msg_free(*msg);
+			free(*msg);
+			*msg = NULL;
+			return ENOMEM;
+		}
+	}
+	
+	/* Add the Message-Authenticator if needed, and other final tasks */
 	if (radius_msg_finish_srv(*msg, cli->key.data, cli->key.len, req->radius.hdr->authenticator)) {
 		TRACE_DEBUG(INFO, "An error occurred while preparing the RADIUS answer");
 		radius_msg_free(*msg);
--- a/extensions/app_radgw/rgw_msg.c	Wed Sep 15 10:44:46 2010 +0900
+++ b/extensions/app_radgw/rgw_msg.c	Wed Sep 15 14:24:45 2010 +0900
@@ -1,106 +0,0 @@
-/*********************************************************************************************************
-* Software License Agreement (BSD License)                                                               *
-* Author: Sebastien Decugis <sdecugis@nict.go.jp>							 *
-*													 *
-* Copyright (c) 2010, 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.								 *
-*********************************************************************************************************/
-
-/* This file contains all support functions to parse, create, and manipulate RADIUS messages. Other 
-modules do not need to "know" the actual representation of RADIUS messages on the network. They only 
-receive the logical view as exposed in the rgw.h file. This file extends the content of the radius.c 
-file functions (from hostap project).*/
-
-#include "rgw.h"
-
-/* Destroy a message */
-void rgw_msg_free(struct rgw_radius_msg_meta ** msg)
-{
-	if (!msg || !*msg)
-		return;
-	
-	radius_msg_free(&(*msg)->radius);
-	free(*msg);
-	*msg = NULL;
-}
-
-/* This function creates a rgw_radius_msg_meta structure after parsing a RADIUS buffer */
-int rgw_msg_parse(unsigned char * buf, size_t len, struct rgw_radius_msg_meta ** msg)
-{
-	struct radius_msg * temp_msg = NULL;
-	
-	TRACE_ENTRY("%p %g %p", buf, len, msg);
-	
-	CHECK_PARAMS( buf && len && msg );
-	
-	*msg = NULL;
-	
-	/* Parse the RADIUS message */
-	temp_msg = radius_msg_parse(buf, len);
-	if (temp_msg == NULL) {
-		TRACE_DEBUG(INFO, "Error parsing the RADIUS message, discarding");
-		return EINVAL;
-	}
-	
-	/* Now alloc space for the meta-data */
-	CHECK_MALLOC( *msg = realloc(temp_msg, sizeof(struct rgw_radius_msg_meta)) );
-	
-	/* Clear memory after the parsed data */
-	memset( &(*msg)->radius + 1, 0, sizeof(struct rgw_radius_msg_meta) - sizeof(struct radius_msg) );
-	
-	return 0;
-}
-
-/* Dump a message (inspired from radius_msg_dump) -- can be used safely with a struct radius_msg as parameter (we don't dump the metadata) */
-void rgw_msg_dump(struct rgw_radius_msg_meta * msg)
-{
-	unsigned char *auth;
-	size_t i;
-	if (! TRACE_BOOL(FULL) )
-		return;
-	
-	auth =  &(msg->radius.hdr->authenticator[0]);
-	
-	fd_log_debug("------ RADIUS msg dump -------\n");
-	fd_log_debug(" id  : 0x%02hhx, code : %hhd (%s)\n", msg->radius.hdr->identifier, msg->radius.hdr->code, rgw_msg_code_str(msg->radius.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->radius.attr_used; i++) {
-		struct radius_attr_hdr *attr = (struct radius_attr_hdr *)(msg->radius.buf + msg->radius.attr_pos[i]);
-		fd_log_debug("    - Type: 0x%02hhx (%s)\n       Len: %-3hhu", attr->type, rgw_msg_attrtype_str(attr->type), attr->length);
-		radius_msg_dump_attr_val(attr);
-	}
-	fd_log_debug("-----------------------------\n");
-}
-
"Welcome to our mercurial repository"