Index: extensions/app_radgw/rgwx_sip.c
===================================================================
--- extensions/app_radgw/rgwx_sip.c	(revision 705)
+++ extensions/app_radgw/rgwx_sip.c	(revision 706)
@@ -58,9 +58,9 @@
 /* This macro converts a RADIUS attribute to a Diameter AVP of type OctetString */
 #define CONV2DIAM_STR( _dictobj_ )	\
-	CHECK_PARAMS( attr->length >= 2 );						\
+	CHECK_PARAMS( attr->length >= sizeof(struct radius_attr_hdr) );			\
 	/* Create the AVP with the specified dictionary model */			\
 	CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) );			\
-	value.os.len = attr->length - 2;						\
-	value.os.data = (unsigned char *)(attr + 1);					\
+	value.os.len = attr->length - sizeof(struct radius_attr_hdr);			\
+	value.os.data = (os0_t)(attr + 1);						\
 	CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );				\
 	/* Add the AVP in the Diameter message. */					\
@@ -68,26 +68,26 @@
 
 #define CONV2DIAM_STR_AUTH( _dictobj_ )	\
-	CHECK_PARAMS( attr->length >= 2 );						\
+	CHECK_PARAMS( attr->length >= sizeof(struct radius_attr_hdr) );			\
 	/* Create the AVP with the specified dictionary model */			\
 	CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) );			\
-	value.os.len = attr->length - 2;						\
-	value.os.data = (unsigned char *)(attr + 1);					\
+	value.os.len = attr->length - sizeof(struct radius_attr_hdr);			\
+	value.os.data = (os0_t)(attr + 1);						\
 	CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );				\
 	/* Add the AVP in the Diameter message. */					\
-	CHECK_FCT( fd_msg_avp_add ( auth, MSG_BRW_LAST_CHILD, avp) );		\
+	CHECK_FCT( fd_msg_avp_add ( auth, MSG_BRW_LAST_CHILD, avp) );			\
 		
 /* Same thing, for scalar AVPs of 32 bits */
 #define CONV2DIAM_32B( _dictobj_ )	\
-	CHECK_PARAMS( attr->length == 6 );						\
+	CHECK_PARAMS( attr->length == sizeof(struct radius_attr_hdr)+sizeof(uint32_t) );\
 	CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) );			\
 	{										\
 		uint8_t * v = (uint8_t *)(attr + 1);					\
 		value.u32  = (v[0] << 24)						\
-		           | (v[1] << 16)						\
-		           | (v[2] <<  8)						\
-		           |  v[3] ;							\
+			   | (v[1] << 16)						\
+			   | (v[2] <<  8)						\
+			   |  v[3] ;							\
 	}										\
 	CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );				\
-	CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+	CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );		\
 				
 				
@@ -145,12 +145,12 @@
 {
 	struct fd_list chain;
-    char * sid;
+    os0_t sid;
     size_t sidlen;
-    char * nonce;
+    os0_t nonce;
     size_t noncelen;
     
 };
 
-static int nonce_add_element(char * nonce, size_t noncelen,char * sid, size_t sidlen, struct rgwp_config * state)
+static int nonce_add_element(os0_t nonce, size_t noncelen, os0_t sid, size_t sidlen, struct rgwp_config * state)
 {
 	CHECK_PARAMS(nonce && state && sid && sidlen && noncelen);
@@ -159,10 +159,8 @@
 	CHECK_MALLOC(newelt=malloc(sizeof(noncechain)));
 	
-	CHECK_MALLOC(newelt->nonce=malloc(noncelen));
-	memcpy(newelt->nonce,nonce,noncelen);
+	CHECK_MALLOC(newelt->nonce= os0dup(nonce, noncelen));
 	newelt->noncelen=noncelen;
 	
-	CHECK_MALLOC(newelt->sid=malloc(sidlen));
-	memcpy(newelt->sid,sid,sidlen);
+	CHECK_MALLOC(newelt->sid=os0dup(sid, sidlen));
 	newelt->sidlen=sidlen;
 	
@@ -198,13 +196,13 @@
 */
 //Retrieve sid from nonce
-static char * nonce_get_sid(char * nonce, size_t noncelen, size_t * sidlen, struct rgwp_config *state)
+static os0_t nonce_get_sid(os0_t nonce, size_t noncelen, size_t * sidlen, struct rgwp_config *state)
 {
 	struct fd_list * li;
-	char *sid=NULL;
+	os0_t sid=NULL;
 	
 	CHECK_PARAMS_DO(nonce && state && noncelen && sidlen, return NULL);
 	*sidlen=0;
 	
-	//**Start mutex
+	// **Start mutex
 	CHECK_POSIX_DO(pthread_mutex_lock(&state->nonce_mutex),); 
 	for(li=state->listnonce.next;li!=&state->listnonce;li=li->next)
@@ -212,5 +210,5 @@
 		noncechain *temp=(noncechain *)li;
 		
-		if(temp->noncelen==noncelen && strncmp(temp->nonce,nonce, noncelen)==0)
+		if (!fd_os_cmp(temp->nonce, temp->noncelen, nonce, noncelen))
 		{
 			fd_list_unlink (li);
@@ -224,5 +222,5 @@
 	}
 	CHECK_POSIX_DO(pthread_mutex_unlock(&state->nonce_mutex),); 
-	//***Stop mutex
+	// ***Stop mutex
 	return sid;
 }
@@ -230,5 +228,5 @@
 static void nonce_deletelistnonce(struct rgwp_config *state)
 {
-	//**Start mutex
+	// **Start mutex
 	CHECK_POSIX_DO(pthread_mutex_lock(&state->nonce_mutex),); 
 	while(!(FD_IS_LIST_EMPTY(&state->listnonce)) )
@@ -243,5 +241,5 @@
 	}
 	CHECK_POSIX_DO(pthread_mutex_unlock(&state->nonce_mutex),); 
-	//***Stop mutex
+	// ***Stop mutex
 }
 
@@ -338,6 +336,7 @@
 	int got_Dresponse = 0;
 	int got_Dalgorithm = 0;
-	char * sid = NULL;
-	char * un=NULL;
+	os0_t sid = NULL;
+	size_t sidlen;
+	os0_t un=NULL;
 	size_t  un_len;
 	size_t nattr_used = 0;
@@ -352,5 +351,5 @@
 	if(*session)
 	{
-		TRACE_DEBUG(INFO,"We are not supposed to receive a session in radSIP plugin.");
+		TRACE_DEBUG(INFO,"INTERNAL ERROR: We are not supposed to receive a session in radSIP plugin.");
 		return EINVAL;
 	}
@@ -371,5 +370,5 @@
 				{
 					TRACE_DEBUG(ANNOYING, "Found a User-Name attribute: '%.*s'", attr->length- sizeof(struct radius_attr_hdr), (char *)(attr+1));
-					un = (char *)(attr + 1);
+					un = (os0_t)(attr + 1);
 					un_len =attr->length - sizeof(struct radius_attr_hdr);
 				}
@@ -396,7 +395,5 @@
 				got_Dnonce = 1;
 				
-				size_t sidlen;
-				
-				sid=nonce_get_sid((char *)(attr+1),attr->length-2,&sidlen,cs);
+				sid=nonce_get_sid((os0_t)(attr+1), attr->length - sizeof(struct radius_attr_hdr), &sidlen, cs);
 				if(!sid)
 				{
@@ -406,5 +403,5 @@
 				CHECK_FCT(fd_sess_fromsid (sid, sidlen, session, NULL));
 				free(sid);
-								
+							
 				
 			break;
@@ -432,6 +429,8 @@
 	if (!*session) {
 		
-		char * fqdn;
-		char * realm;
+		DiamId_t fqdn;
+		size_t fqdn_len;
+		DiamId_t realm;
+		size_t realm_len;
 		
 		
@@ -439,11 +438,10 @@
 		
 		/* Get information on the RADIUS client */
-		CHECK_FCT( rgw_clients_get_origin(cli, &fqdn, &realm) );
-		
-		int len;
+		CHECK_FCT( rgw_clients_get_origin(cli, &fqdn, &fqdn_len, &realm, &realm_len) );
+		
 		/* Create a new Session-Id. The format is: {fqdn;hi32;lo32;username;diamid} */
 		CHECK_MALLOC( sid = malloc(un_len + 1 /* ';' */ + fd_g_config->cnf_diamid_len + 1 /* '\0' */) );
-		len = sprintf(sid, "%.*s;%s", (int)un_len, un, fd_g_config->cnf_diamid);
-		CHECK_FCT( fd_sess_new(session, fqdn, sid, len) );
+		sidlen = sprintf((char *)sid, "%.*s;%s", (int)un_len, un, fd_g_config->cnf_diamid);
+		CHECK_FCT( fd_sess_new(session, fqdn, fqdn_len, sid, sidlen) );
 		free(sid);
 	}
@@ -453,19 +451,19 @@
 	
 	int i = 0;
-	if (un) {
-		/* Is there an '@' in the user name? We don't care for decorated NAI here */
-		for (i = un_len - 2; i > 0; i--) {
-			if (un[i] == '@') {
-				i++;
-				break;
-			}
+	
+	/* Is there an '@' in the user name? We don't care for decorated NAI here */
+	for (i = un_len - 2; i > 0; i--) {
+		if (un[i] == '@') {
+			i++;
+			break;
 		}
 	}
+
 	if (i == 0) {
 		/* Not found in the User-Name => we use the local domain of this gateway */
-		value.os.data = (unsigned char *)fd_g_config->cnf_diamrlm;
+		value.os.data = (os0_t)fd_g_config->cnf_diamrlm;
 		value.os.len  = fd_g_config->cnf_diamrlm_len;
 	} else {
-		value.os.data = (unsigned char *)(un + i);
+		value.os.data = un + i;
 		value.os.len  = un_len - i;
 	}
@@ -475,5 +473,5 @@
 	
 	/* Now, add the Session-Id AVP at beginning of Diameter message */
-	CHECK_FCT( fd_sess_getsid(*session, &sid) );
+	CHECK_FCT( fd_sess_getsid(*session, &sid, &sidlen) );
 	
 	TRACE_DEBUG(FULL, "[sip.rgwx] Translating new message for session '%s'...", sid);
@@ -481,6 +479,6 @@
 	/* Add the Session-Id AVP as first AVP */
 	CHECK_FCT( fd_msg_avp_new ( cs->dict.Session_Id, 0, &avp ) );
-	value.os.data = (unsigned char *)sid;
-	value.os.len = strlen(sid);
+	value.os.data = sid;
+	value.os.len = sidlen;
 	CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
 	CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
@@ -552,5 +550,4 @@
 		CHECK_FCT( fd_msg_avp_add ( auth_data, MSG_BRW_LAST_CHILD, auth) );
 	}
-	char * temp=NULL,*sipuri=NULL;
 
 	for (idx = 0; idx < rad_req->attr_used; idx++) 
@@ -597,19 +594,24 @@
 			{
 				//We extract Realm from Digest_URI
-				char *realm=NULL;
-			
-				CHECK_MALLOC(temp=malloc(attr->length -1));
-				strncpy(temp, (char *)(attr + 1), attr->length -2);
-				temp[attr->length-2] = '\0';
-			
-				realm = strtok( (char *)(temp), "@" );
-				realm = strtok( NULL, "@" );
-				free(temp);
-				temp=NULL;
+				DiamId_t realm=NULL;
+				size_t realm_len;
+				os0_t temp;
+				
+				temp = (os0_t)(attr + 1);
+				
+				for (i=attr->length - sizeof(struct radius_attr_hdr) - 1; i>=0; i--) {
+					if (temp[i] == '@') {
+						realm = (DiamId_t)temp + i + 1;
+						CHECK_FCT_DO( fd_os_validate_DiameterIdentity(&realm, &realm_len, 1),
+							realm = NULL );
+						break;
+					}
+				}
+			
 				if(realm!=NULL)
 				{
 					CHECK_FCT( fd_msg_avp_new ( cs->dict.Digest_Realm, 0, &avp ) );
-					value.os.data=(unsigned char *)realm;
-					value.os.len=strlen(realm);
+					value.os.data=(os0_t)realm;
+					value.os.len=realm_len;
 					CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
 					CHECK_FCT( fd_msg_avp_add ( auth, MSG_BRW_LAST_CHILD, avp) );
@@ -617,9 +619,10 @@
 					//We add SIP-Server-URI AVP because SIP server is registrar (through gateway)
 					CHECK_FCT( fd_msg_avp_new ( cs->dict.SIP_Server_URI, 0, &avp ) );
-					value.os.data=(unsigned char *)realm;
-					value.os.len=strlen(realm);
+					value.os.data=(os0_t)realm;
+					value.os.len=realm_len;
 					CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
 					CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
 					
+					free(realm);
 				}
 				else
@@ -641,18 +644,15 @@
 			//We add SIP-Server-URI AVP because SIP server is registrar (through gateway)
 			CHECK_FCT( fd_msg_avp_new ( cs->dict.SIP_Server_URI, 0, &avp ) );
-			
-			
-			CHECK_MALLOC(temp=malloc(attr->length -1));
-			strncpy(temp, (char *)(attr + 1), attr->length -2);
-			
-			
-			CHECK_MALLOC(sipuri=malloc(attr->length +3));
-			strcpy(sipuri,"sip:");
-			strcat(sipuri,(const char *)temp);
-			value.os.data=(unsigned char *)sipuri;
-			value.os.len=attr->length +2;
+			os0_t temp;
+			#define SIP_PREFIX	"sip:"
+			size_t temp_len = attr->length - sizeof(struct radius_attr_hdr) + CONSTSTRLEN(SIP_PREFIX) + 1;
+			CHECK_MALLOC( temp = malloc(temp_len) );
+			temp_len = snprintf((char *)temp, temp_len, SIP_PREFIX "%.*s", attr->length - sizeof(struct radius_attr_hdr), (char *)(attr + 1));
+			
+			value.os.data=temp;
+			value.os.len=temp_len;
 			
 			free(temp);
-			temp=NULL;
+			
 			CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
 			CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
@@ -689,9 +689,10 @@
 			{
 				//[Note 3] If Digest-Algorithm is missing, 'MD5' is assumed.
+				#define DIGEST_ALGO_MD5	"MD5"
 										
 				CHECK_FCT( fd_msg_avp_new ( cs->dict.Digest_Algorithm, 0, &avp ) );			
 										
-				value.os.data = (unsigned char *)"MD5";
-				value.os.len = strlen((const char *)value.os.data);
+				value.os.data = (os0_t)DIGEST_ALGO_MD5;
+				value.os.len = CONSTSTRLEN(DIGEST_ALGO_MD5) - 1;
 				CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );					
 				CHECK_FCT( fd_msg_avp_add ( auth, MSG_BRW_LAST_CHILD, avp) );	
@@ -831,10 +832,9 @@
 					/* Retrieve the request identified which was stored in the session */
 					if (session) {
-						char *sid=NULL;
+						os0_t sid=NULL;
 						size_t sidlen;
-						fd_sess_getsid (session, &sid );
-						sidlen=strlen(sid);
+						fd_sess_getsid (session, &sid, &sidlen );
 						
-						nonce_add_element((char *)ahdr->avp_value->os.data,ahdr->avp_value->os.len, sid,sidlen, cs);
+						nonce_add_element(ahdr->avp_value->os.data, ahdr->avp_value->os.len, sid, sidlen, cs);
 					}
 					break;
