view extensions/app_sip/userauthorization.c @ 1510:a2fb51309cd2

Add 3GPP TS 29.345 V15.1.0 (2019-09) Add AVPs: - App-Layer-User-Id, UTF8String, code 3801, section 6.3.2 - Assistance-info, Grouped, code 3802, section 6.3.3 - Assistance-Info-Validity-Timer, Unsigned32, code 3803, section 6.3.4 - Discovery-Type, Unsigned32, code 3804, section 6.3.5 - Filter-Id, OctetString, code 3805, section 6.3.9 - MAC-Address, UTF8String, code 3806, section 6.3.11 - Match-Report, Grouped, code 3807, section 6.3.12 - Operating-Channel, Unsigned32, code 3808, section 6.3.14 - P2P-Features, Unsigned32, code 3809, section 6.3.15 - ProSe-App-Code, OctetString, code 3810, section 6.3.16 - ProSe-App-Id, UTF8String, code 3811, section 6.3.17 - ProSe-App-Mask, OctetString, code 3812, section 6.3.18 - ProSe-Discovery-Filter, Grouped, code 3813, section 6.3.20 - PRR-Flags, Unsigned32, code 3814, section 6.3.21 - ProSe-Validity-Timer, Unsigned32, code 3815, section 6.3.22 - Requesting-EPUID, UTF8String, code 3816, section 6.3.23 - Targeted-EPUID, UTF8String, code 3817, section 6.3.26 - Time-Window, Unsigned32, code 3818, section 6.3.27 - WiFi-P2P-Assistance-Info, Grouped, code 3819, section 6.3.30 - WLAN-Assistance-Info, Grouped, code 3820, section 6.3.31 - WLAN-Link-Layer-Id, OctetString, code 3821, section 6.3.32 - WLAN-Link-Layer-Id-List, Grouped, code 3822, section 6.3.33 - Location-Update-Trigger, Grouped, code 3823, section 6.3.42 - Location-Update-Event-Type, Unsigned32, code 3824, section 6.3.43 - Change-Of-Area-Type, Grouped, code 3825, section 6.3.44 - Location-Update-Event-Trigger, Unsigned32, code 3826, section 6.3.45 - Report-Cardinality, Enumerated, code 3827, section 6.3.46 - Minimum-Interval-Time, Unsigned32, code 3828, section 6.3.47 - Periodic-Location-Type, Grouped, code 3829, section 6.3.48 - Location-Report-Interval-Time, Unsigned32, code 3830, section 6.3.49 - Total-Number-Of-Reports, Unsigned32, code 3831, section 6.3.50 - Validity-Time-Announce, Unsigned32, code 3832, section 6.3.36 - Validity-Time-Monitor, Unsigned32, code 3833, section 6.3.37 - Validity-Time-Communication, Unsigned32, code 3834, section 6.3.38 - ProSe-App-Code-Info, Grouped, code 3835, section 6.3.39 - MIC, OctetString, code 3836, section 6.3.40 - UTC-based-Counter, Unsigned32, code 3837, section 6.3.41 - ProSe-Match-Refresh-Timer, Unsigned32, code 3838, section 6.3.52 - ProSe-Metadata-Index-Mask, OctetString, code 3839, section 6.3.60 - App-Identifier, Grouped, code 3840, section 6.3.61 - OS-ID, OctetString, code 3841, section 6.3.62 - OS-App-ID, UTF8String, code 3842, section 6.3.63 - Requesting-RPAUID, UTF8String, code 3843, section 6.3.64 - Target-RPAUID, UTF8String, code 3844, section 6.3.65 - Target-PDUID, OctetString, code 3845, section 6.3.66 - ProSe-Restricted-Code, OctetString, code 3846, section 6.3.67 - ProSe-Restricted-Code-Suffix-Range, OctetString, code 3847, section 6.3.68 - Beginning-Suffix, OctetString, code 3848, section 6.3.69 - Ending-Suffix, OctetString, code 3849, section 6.3.70 - Discovery-Entry-ID, Unsigned32, code 3850, section 6.3.59 - Match-Timestamp, Time, code 3851, section 6.3.71 - PMR-Flags, Unsigned32, code 3852, section 6.3.57 - ProSe-Application-Metadata, UTF8String, code 3853, section 6.3.58 - Discovery-Auth-Request, Grouped, code 3854, section 6.3.53 - Discovery-Auth-Response, Grouped, code 3855, section 6.3.54 - Match-Request, Grouped, code 3856, section 6.3.55 - Match-Report-Info, Grouped, code 3857, section 6.3.56 - Banned-RPAUID, UTF8String, code 3858, section 6.3.73 - Banned-PDUID, OctetString, code 3859, section 6.3.74 - Code-Receiving-Security-Material, Grouped, code 3860, section 6.3.75 - Code-Sending-Security-Material, Grouped, code 3861, section 6.3.76 - DUSK, OctetString, code 3862, section 6.3.77 - DUIK, OctetString, code 3863, section 6.3.78 - DUCK, OctetString, code 3864, section 6.3.79 - MIC-Check-indicator, Unsigned32, code 3865, section 6.3.80 - Encrypted-Bitmask, OctetString, code 3866, section 6.3.81 - ProSe-App-Code-Suffix-Range, OctetString, code 3867, section 6.3.82 - PC5-tech, OctetString, code 3868, section 6.3.84 Note: Name conflict with 3GPP TS 29.154 Time-Window (4204). Time-Window (3818) in 3GPP TS 29.345 V12.1.0 (2014-12) predates Time-Window (4204) in 3GPP TS 29.154 V13.1.0 (2016-03).
author Luke Mewburn <luke@mewburn.net>
date Sun, 05 Apr 2020 08:27:37 +1000
parents 95a784729cac
children
line wrap: on
line source

/*********************************************************************************************************
* Software License Agreement (BSD License)                                                               *
* Author: Alexandre Westfahl <awestfahl@freediameter.net>						 *
*													 *
* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (Keio University), and the WIDE Project. 	 *		
*													 *
* 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 Teraoka Laboratory nor the 							 *
*   names of its contributors may be used to endorse or 						 *
*   promote products derived from this software without 						 *
*   specific prior written permission of Teraoka Laboratory 						 *
*   													 *
* 													 *
* 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 "app_sip.h"


int app_sip_UAR_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, void * opaque, enum disp_action * act)
{
	TRACE_ENTRY("%p %p %p %p", msg, paramavp, sess, act);
	
	struct msg *ans, *qry;
	struct avp *avp, *groupedavp=NULL;
	struct avp_hdr *avphdr, *sipaorhdr, *visitednethdr, *usernamehdr;
	union avp_value value;
	int ret=0, hascap=0;
	
	//Result_Code to return in the answer
	char result[55];
	
	if (msg == NULL)
		return EINVAL;

	
	// Create answer header 
	qry = *msg;
	CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
	ans = *msg;
	
	//Add the Auth-Application-Id 
	{
		CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Application_Id, 0, &avp ) );
		value.i32 = 6;
		CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
		CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, avp) );
	}
	// Add the Auth-Session-State AVP 
	{
		
		CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.Auth_Session_State, &avp) );
		CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr )  );
		
		CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
		CHECK_FCT( fd_msg_avp_setvalue( avp, avphdr->avp_value ) );
		CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
	}
	
	//Retrieve SIP-AOR
	{
		CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_AOR, &avp) );
		CHECK_FCT( fd_msg_avp_hdr( avp, &sipaorhdr )  );
	}
	
	//We check if we have a User-Name AVP
	{
		CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.User_Name, &avp) );
		if(avp!=NULL)
		{
			CHECK_FCT( fd_msg_avp_hdr( avp, &usernamehdr )  );
			
			ret=get_password(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len, NULL);
			
			
			if(ret==1)
			{//not found
				strcpy(result,"DIAMETER_ERROR_USER_UNKNOWN");
				goto out;
			}
			else if(ret==2)
			{//error
				//We couldn't make the request, we must stop process!
				strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
				goto out;
			}
			else if(ret==0)
			{//found
				
				//We must check that this user can use this SIP-AOR
				ret=check_sipaor(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len, (const char *)sipaorhdr->avp_value->os.data,sipaorhdr->avp_value->os.len);
				
				if(ret==0)
				{
					//The SIP-AOR and Username are ok!
				}
				else if(ret==1)
				{//not found
					strcpy(result,"DIAMETER_ERROR_IDENTITIES_DONT_MATCH");
					goto out;
				}
				else
				{//error
					//We couldn't make the request, we must stop process!
					strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
					goto out;
				}
			}
		}
	}
	
	//We check if we have a SIP-Visited-Network-Id AVP
	{
		CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Visited_Network_Id, &avp) );
		
		if(avp!=NULL)
		{
			CHECK_FCT( fd_msg_avp_hdr( avp, &visitednethdr )  );
		}
		else
			visitednethdr=NULL;
	}
	
	//We check if we have a SIP_User_Authorization_Type
	{
		int auth_type;
		
		CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_User_Authorization_Type, &avp) );
		
		if(avp!=NULL)
		{
			CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr )  );
			auth_type=avphdr->avp_value->i32;
			
			if(auth_type==0 || auth_type==2)
			{
				if(visitednethdr!=NULL)
				{
					/*
					If there is a SIP-Visited-Network-Id AVP in the Diameter UAR message,
					and the SIP-User-Authorization-Type AVP value received in the
					Diameter UAR message is set to REGISTRATION or REGISTRATION&
					CAPABILITIES, then the Diameter server SHOULD verify whether the user
					is allowed to roam into the network specified in the
					SIP-Visited-Network-Id AVP in the Diameter UAR message.  If the user
					is not allowed to roam into that network, the Diameter AAA server
					MUST set the Result-Code AVP value in the Diameter UAA message to
					DIAMETER_ERROR_ROAMING_NOT_ALLOWED.
					*/
					ret=allow_roaming(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len, (const char *)visitednethdr->avp_value->os.data,visitednethdr->avp_value->os.len);
					
					if(ret==0)
					{
						//This user can come in this network
					}
					else if(ret==1)
					{
						strcpy(result,"DIAMETER_ERROR_ROAMING_NOT_ALLOWED");
						goto out;
					}
					else
					{
						strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
						goto out;
					}
					
				}
				/*
				If the SIP-User-Authorization-Type AVP value received in the Diameter
				UAR message is set to REGISTRATION or REGISTRATION&CAPABILITIES, then
				the Diameter server SHOULD verify whether the SIP-AOR AVP value is
				authorized to register in the Home Realm.  Where the SIP AOR is not
				authorized to register in the Home Realm, the Diameter server MUST
				set the Result-Code AVP to DIAMETER_AUTHORIZATION_REJECTED and send
				it in a Diameter UAA message.
				*/
				ret=exist_username(sipaorhdr->avp_value->os.data, sipaorhdr->avp_value->os.len);
				if(ret==0)
				{
					//The SIP_AOR exists in this realm
				}
				else if(ret==1)
				{
					strcpy(result,"DIAMETER_AUTHORIZATION_REJECTED");
					goto out;
				}
				else
				{
					strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
					goto out;
				}
			}
		}
		else
			auth_type=0; //Registration only (default value if absent)
		
		
		//Let's look for the SIP_Server_URI'
		unsigned char *sipserver_uri;
		size_t sipserverurilen;
		
		ret=get_sipserver_uri(sipaorhdr->avp_value->os.data, sipaorhdr->avp_value->os.len, &sipserver_uri, &sipserverurilen);
		
		if(ret==0)
		{//We know a SIP Server so we must provide it
			//We only add this AVP when we have registration or deregistration
			if(auth_type==0 ||auth_type==1)
			{
				CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Server_URI, 0, &avp ) );
				value.os.data=sipserver_uri;
				value.os.len=sipserverurilen;
				CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
				CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
			}
		}
		else if(ret==1)
		{
			sipserver_uri=NULL;
			sipserverurilen=0;
			
		}
		else
		{
			strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
			goto out;
		}
		
		//If we have a REGISTRATION or REGISTRATION & CAPABILITIES
		if(auth_type==0 ||auth_type==2)
		{
			//Adding SIP-Server-Capabilities
			CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Server_Capabilities, 0, &groupedavp ) );
			
			ret=get_sipserver_cap(sipaorhdr->avp_value->os.data, sipaorhdr->avp_value->os.len,&groupedavp);
			
			if(ret==0)
			{
				CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, groupedavp) );
				hascap=1;
			}
			else if(ret==1)
			{
				
				hascap=0;
			}
			else
			{
				CHECK_FCT( fd_msg_free( groupedavp ) );
				strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
				goto out;
			}
		}
		
		
		
		if(auth_type==0)
		{//Registration
			
			if(sipserver_uri==NULL)
			{
				strcpy(result,"DIAMETER_FIRST_REGISTRATION");
			}
			else
			{
				if(hascap==1)
				{
					strcpy(result,"DIAMETER_SERVER_SELECTION");
				}
				else
				{
					//We free the Capabilities AVP because we didn't found any'
					if(groupedavp!=NULL)
						CHECK_FCT( fd_msg_free( groupedavp ) );
					strcpy(result,"DIAMETER_SUBSEQUENT_REGISTRATION");
				}
			}
		}
		else if(auth_type==2)
		{//Registration & Capabilities
			//We let the groupedavp in the message even if there is no capabilities
			
			if(hascap==0)
			{
				CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, groupedavp) );
			}
			strcpy(result,"DIAMETER_SUCCESS");	
		}
		else if(auth_type==1)
		{//Deregistration
			if(sipserver_uri==NULL)
			{
				strcpy(result,"DIAMETER_ERROR_IDENTITY_NOT_REGISTERED");
			}
			else
			{
				strcpy(result,"DIAMETER_SUCCESS");	
			}
		}
		else
		{//We should never be here!!
			strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
			goto out;
		}
	}
	
	
out:
	CHECK_FCT( fd_msg_rescode_set( ans, result, NULL, NULL, 1 ) );
	
	
	//fd_msg_dump_walk(INFO,ans);
	
	CHECK_FCT( fd_msg_send( msg, NULL, NULL ));
	
	
	
	return 0;
}
"Welcome to our mercurial repository"