# HG changeset patch # User Alexandre Westfahl # Date 1280147967 -32400 # Node ID 3d9f300f3b49f18cfe0b7ba50eb4ed157ee14c50 # Parent 44541db912a2aec467c05da09f296931fc3c0953 Added SAR/SAA and UAR/UAA diff -r 44541db912a2 -r 3d9f300f3b49 extensions/app_sip/CMakeLists.txt --- a/extensions/app_sip/CMakeLists.txt Mon Jul 26 18:33:50 2010 +0900 +++ b/extensions/app_sip/CMakeLists.txt Mon Jul 26 21:39:27 2010 +0900 @@ -20,7 +20,9 @@ md5.c multimediaauth.c registrationtermination.c + userauthorization.c pushprofile.c + serverassignment.c locationinfo.c locationinfosl.c ) diff -r 44541db912a2 -r 3d9f300f3b49 extensions/app_sip/TODO --- a/extensions/app_sip/TODO Mon Jul 26 18:33:50 2010 +0900 +++ b/extensions/app_sip/TODO Mon Jul 26 21:39:27 2010 +0900 @@ -37,3 +37,20 @@ TODO List * add in malloc the size of char +* when getting results from mysql, check lenght +* sort capabilities in LIR/LIA +* remove warnings in SIP plugin for gateway +* make functions for database access in MAR/MAA +* order diamsip.h because it's becoming a mess ^^ +* replace password in MAR/MAA and libdiamsip from table to malloc char! +* display errors of mysql +* check that all user data inserted in requests are purified +* add accounting server uri in database and diamsip +* add mutex on mysql writing +* check multithreading of mysql! + + + + + + diff -r 44541db912a2 -r 3d9f300f3b49 extensions/app_sip/diamsip.c --- a/extensions/app_sip/diamsip.c Mon Jul 26 18:33:50 2010 +0900 +++ b/extensions/app_sip/diamsip.c Mon Jul 26 21:39:27 2010 +0900 @@ -125,6 +125,7 @@ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Session-State", &sip_dict.Auth_Session_State, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Application-Id", &sip_dict.Auth_Application_Id, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Host", &sip_dict.Destination_Host, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Realm", &sip_dict.Destination_Realm, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &sip_dict.Session_Id, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Redirect-Host", &sip_dict.Redirect_Host, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Redirect-Host-Usage", &sip_dict.Redirect_Host_Usage, ENOENT) ); @@ -135,11 +136,26 @@ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authentication-Scheme", &sip_dict.SIP_Authentication_Scheme, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authentication-Info", &sip_dict.SIP_Authentication_Info, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Server-URI", &sip_dict.SIP_Server_URI, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Server-Capabilities", &sip_dict.SIP_Server_Capabilities, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Mandatory-Capability", &sip_dict.SIP_Mandatory_Capability, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Optional-Capability", &sip_dict.SIP_Optional_Capability, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Method", &sip_dict.SIP_Method, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-AOR", &sip_dict.SIP_AOR, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Deregistration-Reason", &sip_dict.SIP_Deregistration_Reason, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Reason-Code", &sip_dict.SIP_Reason_Code, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Reason-Info", &sip_dict.SIP_Reason_Info, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Accounting-Information", &sip_dict.SIP_Accounting_Information, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Accounting-Server-URI", &sip_dict.SIP_Accounting_Server_URI, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Credit-Control-Server-URI", &sip_dict.SIP_Credit_Control_Server_URI, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Server-Assignment-Type", &sip_dict.SIP_Server_Assignment_Type, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Item-Number", &sip_dict.SIP_Item_Number, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Authorization-Type", &sip_dict.SIP_User_Authorization_Type, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Supported-User-Data-Type", &sip_dict.SIP_Supported_User_Data_Type, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Data", &sip_dict.SIP_User_Data, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Data-Type", &sip_dict.SIP_User_Data_Type, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Data-Contents", &sip_dict.SIP_User_Data_Contents, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Data-Already-Available", &sip_dict.SIP_User_Data_Already_Available, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Visited-Network-Id", &sip_dict.SIP_Visited_Network_Id, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Realm", &sip_dict.Digest_Realm, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-URI", &sip_dict.Digest_URI, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Nonce", &sip_dict.Digest_Nonce, ENOENT) ); @@ -175,6 +191,12 @@ //LIR CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Location-Info-Request", &data.command, ENOENT) ); CHECK_FCT( fd_disp_register( diamsip_LIR_cb, DISP_HOW_CC, &data, &diamsip_LIR_hdl ) ); + //UAR + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "User-Authorization-Request", &data.command, ENOENT) ); + CHECK_FCT( fd_disp_register( diamsip_UAR_cb, DISP_HOW_CC, &data, &diamsip_UAR_hdl ) ); + //SAR + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Server-Assignment-Request", &data.command, ENOENT) ); + CHECK_FCT( fd_disp_register( diamsip_SAR_cb, DISP_HOW_CC, &data, &diamsip_SAR_hdl ) ); } if(as_conf->mode==2) { @@ -204,10 +226,6 @@ TRACE_DEBUG(INFO,"Creation of thread failed, abort!"); return EINVAL; } - - - - return 0; diff -r 44541db912a2 -r 3d9f300f3b49 extensions/app_sip/diamsip.h --- a/extensions/app_sip/diamsip.h Mon Jul 26 18:33:50 2010 +0900 +++ b/extensions/app_sip/diamsip.h Mon Jul 26 21:39:27 2010 +0900 @@ -87,6 +87,19 @@ void request_mysql(char *query); void close_mysql_connection(); int get_diameter_uri(const unsigned char *sip_aor, const size_t sipaorlen, char ** diameter_uri, size_t *diameterurilen); +int exist_username(const unsigned char *sip_aor, const size_t sipaorlen); +int get_sipserver_cap(const unsigned char *sip_aor, const size_t sipaorlen, struct avp **capabilities); +int get_password(const unsigned char *username, const size_t usernamelen, char *password); +int check_sipaor(const unsigned char *username, const size_t usernamelen, const char * sip_aor,const size_t sipaorlen); +int get_user_datatype(const unsigned char *username, const size_t usernamelen,char **table_supported, const int num_elements, struct avp **groupedavp); +int set_pending_flag(const unsigned char *username, const size_t usernamelen); +int clear_pending_flag(const unsigned char *username, const size_t usernamelen); +int set_real_sipserver_uri(const unsigned char *username, const size_t usernamelen, const unsigned char *sipserver_uri,const size_t sipserverurilen); +int set_sipserver_uri(const unsigned char *username, const size_t usernamelen, const unsigned char *sipserver_uri,const size_t sipserverurilen); + +//count functions +int count_supporteddatatype(const struct msg * message); +int count_sipaor(const struct msg * message); void DigestCalcHA1(char * pszAlg,char * pszUserName,char * pszRealm,char * pszPassword,char * pszNonce,char * pszCNonce,HASHHEX SessionKey); @@ -129,6 +142,8 @@ int diamsip_RTA_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act); int diamsip_PPA_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act); int diamsip_LIR_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act); +int diamsip_UAR_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act); +int diamsip_SAR_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act); //Suscriber Locator int diamsipSL_LIR_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, enum disp_action * act); @@ -137,20 +152,55 @@ #define SQL_GETPASSWORD "SELECT `password` FROM ds_users WHERE `username` ='%s'" #define SQL_GETPASSWORD_LEN 52 +//username by SIP-AOR +#define SQL_GETUSERNAME "SELECT `username` FROM ds_users, ds_sip_aor WHERE `sip_aor` ='%s' AND `ds_sip_aor`.`id_user` = `ds_users`.`id_user`" +#define SQL_GETUSERNAME_LEN 113 + +//sip server uri by username #define SQL_GETSIPURI "SELECT `sip_server_uri` FROM ds_users WHERE `username` ='%s'" #define SQL_GETSIPURI_LEN 60 +//sip server uri by SIP-AOR +#define SQL_GETSIPSERURI "SELECT `sip_server_uri` FROM ds_users, ds_sip_aor WHERE `sip_aor` ='%s' AND `ds_sip_aor`.`id_user` = `ds_users`.`id_user`" +#define SQL_GETSIPSERURI_LEN 119 + +//sip capabilities for a SIP-AOR +#define SQL_GETSIPSERCAP "SELECT `compulsory`,`id_service` FROM ds_user_services, ds_sip_aor WHERE `sip_aor` ='%s' AND `ds_sip_aor`.`id_user` = `ds_user_services`.`id_user`" +#define SQL_GETSIPSERCAP_LEN 144 + +//user data for a user data supported +#define SQL_GETUSEDATA "SELECT `data_type`,`data` FROM ds_users, ds_user_data, ds_data_types WHERE `username` ='%s' AND `ds_users`.`id_user` = `ds_user_data`.`id_user` AND `ds_data_types`.`id_data_type`=`ds_user_data`.`id_data_type`" +#define SQL_GETUSEDATA_LEN 206 + #define SQL_GETDIAMURI "SELECT `diameter_uri` FROM sl_sip_aor_map WHERE `sip_aor` ='%s'" #define SQL_GETDIAMURI_LEN 61 -#define SQL_SETSIPURI "UPDATE ds_users SET `sip_server_uri`='%s', `flag`=1 WHERE `username` ='%s'" -#define SQL_SETSIPURI_LEN 74 +//networks for this user +#define SQL_GETUSERNET "SELECT `label_network` FROM ds_users, ds_user_networks, ds_networks WHERE `ds_users`.`username` ='%s' AND `ds_user_networks`.`id_user` = `ds_users`.`id_user` AND `ds_user_networks`.`id_network` = `ds_networks`.`id_network`" +#define SQL_GETUSERNET_LEN 220 + +#define SQL_SETSIPURI "UPDATE ds_users SET `temp_sip_server_uri`='%s' WHERE `username` ='%s'" +#define SQL_SETSIPURI_LEN 65 + +//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO +#define SQL_RMSIPURI "UPDATE ds_users SET `temp_sip_server_uri`='', `sip_server_uri`='' WHERE `id_user` ='%s'" +#define SQL_RMSIPURI_LEN 65 +//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO + +#define SQL_SETREALSIPURI "UPDATE ds_users SET `sip_server_uri`='%s' WHERE `username` ='%s'" +#define SQL_SETREALSIPURI_LEN 65 + +#define SQL_SETFLAG "UPDATE ds_users SET `authentication_pending`=1 WHERE `username` ='%s'" +#define SQL_SETFLAG_LEN 67 + +#define SQL_CLEARFLAG "UPDATE ds_users SET `authentication_pending`=0, `registrated`=1 WHERE `username` ='%s'" +#define SQL_CLEARFLAG_LEN 84 #define SQL_GETSIPAOR "SELECT `sip_aor` FROM `ds_sip_aor`, `ds_users` WHERE `ds_sip_aor`.`id_user` = `ds_users`.`id_user` AND `ds_users`.`username` = '%s'" #define SQL_GETSIPAOR_LEN 131 -#define SQL_CLEARFLAG "UPDATE ds_users SET `flag`=0 WHERE `username` ='%s'" -#define SQL_CLEARFLAG_LEN 74 +//#define SQL_CLEARFLAG "UPDATE ds_users SET `authentication_pending`=0 WHERE `username` ='%s'" +//#define SQL_CLEARFLAG_LEN 67 extern struct session_handler * ds_sess_hdl; @@ -166,17 +216,33 @@ struct dict_object * Auth_Session_State; struct dict_object * Auth_Application_Id; struct dict_object * Destination_Host; + struct dict_object * Destination_Realm; struct dict_object * User_Name; struct dict_object * Session_Id; struct dict_object * Redirect_Host; struct dict_object * Redirect_Host_Usage; struct dict_object * SIP_Auth_Data_Item; + struct dict_object * SIP_Accounting_Information; + struct dict_object * SIP_Accounting_Server_URI; + struct dict_object * SIP_Credit_Control_Server_URI; + struct dict_object * SIP_Server_Assignment_Type; + struct dict_object * SIP_Item_Number; + struct dict_object * SIP_User_Authorization_Type; + struct dict_object * SIP_Supported_User_Data_Type; + struct dict_object * SIP_User_Data; + struct dict_object * SIP_User_Data_Type; + struct dict_object * SIP_User_Data_Contents; + struct dict_object * SIP_User_Data_Already_Available; + struct dict_object * SIP_Visited_Network_Id; struct dict_object * SIP_Authorization; struct dict_object * SIP_Authenticate; struct dict_object * SIP_Number_Auth_Items; struct dict_object * SIP_Authentication_Scheme; struct dict_object * SIP_Authentication_Info; struct dict_object * SIP_Server_URI; + struct dict_object * SIP_Server_Capabilities; + struct dict_object * SIP_Mandatory_Capability; + struct dict_object * SIP_Optional_Capability; struct dict_object * SIP_Method; struct dict_object * SIP_AOR; struct dict_object * SIP_Deregistration_Reason; diff -r 44541db912a2 -r 3d9f300f3b49 extensions/app_sip/libdiamsip.c --- a/extensions/app_sip/libdiamsip.c Mon Jul 26 18:33:50 2010 +0900 +++ b/extensions/app_sip/libdiamsip.c Mon Jul 26 21:39:27 2010 +0900 @@ -165,7 +165,7 @@ } -//You must free ""result"" after using this function + void request_mysql(char *query) { //We check if the connection is still up @@ -185,69 +185,177 @@ } +//If password is null, we just verify this user exist +//We don't need the password length because it is a table' +int get_password(const unsigned char *username, const size_t usernamelen, char *password) +{ + CHECK_PARAMS(username && usernamelen); + + int not_found=2; + size_t querylen, usernamepurelen; + char *query, *username_pure; + + switch(as_conf->datasource) + { + //MySQL + case ASMYSQL: + //We allocate the double size of username because at worst it can be all quotes + username_pure=malloc(usernamelen*2+1); + //We purify username not to have forbidden characters + usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen); + + //We copy username in query + querylen=SQL_GETPASSWORD_LEN + usernamepurelen; + query = malloc(querylen+2); + snprintf(query, querylen+1, SQL_GETPASSWORD, username_pure); + + MYSQL_RES *res; + MYSQL_ROW row; + + //We make the query + request_mysql(query); + res=mysql_use_result(conn); + if(res==NULL) + { + if(password!=NULL) + password[0]='\0'; + free(query); + return 2; + } + + + + while ((row = mysql_fetch_row(res)) != NULL) + { + if(strlen(row[0])>0) + { + if(password!=NULL) + strcpy(password,row[0]); + + not_found=0; + break; + } + } + mysql_free_result(res); + free(query); + break; + } + return not_found; +} + +int check_sipaor(const unsigned char *username, const size_t usernamelen, const char * sip_aor,const size_t sipaorlen) +{ + CHECK_PARAMS(username && usernamelen && sip_aor && sipaorlen); + + int not_found=2; + size_t querylen, usernamepurelen; + char *query, *username_pure; + + switch(as_conf->datasource) + { + //MySQL + case ASMYSQL: + //We allocate the double size of username because at worst it can be all quotes + username_pure=malloc(usernamelen*2+1); + //We purify username not to have forbidden characters + usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen); + + //We get the list of AOR owned by this user + querylen=SQL_GETSIPAOR_LEN + usernamepurelen; + query = malloc(querylen+2); + snprintf(query, querylen+1, SQL_GETSIPAOR, username_pure); + + MYSQL_RES *res; + MYSQL_ROW row; + + //We make the query + request_mysql(query); + res=mysql_use_result(conn); + if(res==NULL) + { + free(query); + return 2; + } + + + not_found=1; + while ((row = mysql_fetch_row(res)) != NULL) + { + if(strncmp((const char *)sip_aor,row[0],sipaorlen)==0) + { + not_found=0; + break; + } + } + mysql_free_result(res); + free(query); + break; + } + return not_found; +} + int get_diameter_uri(const unsigned char *sip_aor, const size_t sipaorlen, char ** diameter_uri, size_t *diameterurilen) { - CHECK_PARAMS(sip_aor && sipaorlen); - - size_t querylen, sipaorpurelen; - char *query, *sipaor_pure; - int not_found=1; - - - - - //a sip aor must begin by "sip:" or "sips:" so it must at least be longer than 4 chars - if(sipaorlen<5) - return 2; - - //NOTE: each method has to purify sip_aor itself. You must remove quotes or special chars for security - - switch(as_conf->datasource) - { - //MySQL - case ASMYSQL: + CHECK_PARAMS(sip_aor && sipaorlen); + + size_t querylen, sipaorpurelen; + char *query, *sipaor_pure; + int not_found=2; + + + + + //a sip aor must begin by "sip:" or "sips:" so it must at least be longer than 4 chars + if(sipaorlen<5) + return 2; + + //NOTE: each method has to purify sip_aor itself. You must remove quotes or special chars for security + switch(as_conf->datasource) + { + //MySQL + case ASMYSQL: + + querylen=SQL_GETDIAMURI_LEN + sipaorlen; - querylen=SQL_GETDIAMURI_LEN + sipaorlen; - - - //We allocate the double size of SIP-URI because at worst it can be all quotes - CHECK_MALLOC(sipaor_pure=malloc(sipaorlen*2+1)); - //We purify SIP-URI not to have forbidden characters - sipaorpurelen=mysql_real_escape_string(conn, sipaor_pure, (const char *)sip_aor, sipaorlen); - - - query = malloc(querylen+sipaorpurelen+ 2); - snprintf(query, querylen+1, SQL_GETDIAMURI, sipaor_pure); - - MYSQL_RES *res; - MYSQL_ROW row; - + + //We allocate the double size of SIP-URI because at worst it can be all quotes + CHECK_MALLOC(sipaor_pure=malloc(sipaorlen*2+1)); + //We purify SIP-URI not to have forbidden characters + sipaorpurelen=mysql_real_escape_string(conn, sipaor_pure, (const char *)sip_aor, sipaorlen); + + + query = malloc(querylen+sipaorpurelen+ 2); + snprintf(query, querylen+1, SQL_GETDIAMURI, sipaor_pure); + + MYSQL_RES *res; + MYSQL_ROW row; + - //We make the query - request_mysql(query); - res=mysql_use_result(conn); - if(res==NULL) - { - //We couldn't make the request - diameter_uri=NULL; - return 2; - } - TRACE_DEBUG(INFO,"***********%d|%d****************\n%s\n*********************************",sipaorlen,sipaorpurelen,query); - while ((row = mysql_fetch_row(res)) != NULL) - { - *diameterurilen=strlen(row[0]); - if(*diameterurilen>0) - { - CHECK_MALLOC(*diameter_uri=malloc(*diameterurilen+1)); - strcpy(*diameter_uri,row[0]); - not_found=0; - break; - } - } - mysql_free_result(res); - free(query); - free(sipaor_pure); - break; + //We make the query + request_mysql(query); + res=mysql_use_result(conn); + if(res==NULL) + { + //We couldn't make the request + diameter_uri=NULL; + return 2; + } + + while ((row = mysql_fetch_row(res)) != NULL) + { + *diameterurilen=strlen(row[0]); + if(*diameterurilen>0) + { + CHECK_MALLOC(*diameter_uri=malloc(*diameterurilen+1)); + strcpy(*diameter_uri,row[0]); + not_found=0; + break; + } + } + mysql_free_result(res); + free(query); + free(sipaor_pure); + break; default: @@ -264,6 +372,633 @@ } +int exist_username(const unsigned char *sip_aor, const size_t sipaorlen) +{ + CHECK_PARAMS(sip_aor && sipaorlen); + + size_t querylen, sipaorpurelen; + char *query, *sipaor_pure; + int not_found=1; + + //a sip aor must begin by "sip:" or "sips:" so it must at least be longer than 4 chars + if(sipaorlen<5) + return 2; + + //NOTE: each method has to purify sip_aor itself. You must remove quotes or special chars for security + + switch(as_conf->datasource) + { + //MySQL + case ASMYSQL: + + querylen=SQL_GETUSERNAME_LEN + sipaorlen; + + + //We allocate the double size of SIP-URI because at worst it can be all quotes + CHECK_MALLOC(sipaor_pure=malloc(sipaorlen*2+1)); + //We purify SIP-URI not to have forbidden characters + sipaorpurelen=mysql_real_escape_string(conn, sipaor_pure, (const char *)sip_aor, sipaorlen); + + + query = malloc(querylen+sipaorpurelen+ 2); + snprintf(query, querylen+1, SQL_GETUSERNAME, sipaor_pure); + + MYSQL_RES *res; + MYSQL_ROW row; + + + //We make the query + request_mysql(query); + res=mysql_use_result(conn); + if(res==NULL) + { + //We couldn't make the request + return 2; + } + + while ((row = mysql_fetch_row(res)) != NULL) + { + if(strlen(row[0])>0) + { + not_found=0; + break; + } + } + mysql_free_result(res); + free(query); + free(sipaor_pure); + break; + + default: + + //We must never go here, if so, we must stop diameter_sip + TRACE_DEBUG(INFO,"FATAL ERROR: the datasource is unknown, please check your config file!"); + return 2; + + break; + } + + //0 if it was found + return not_found; + +} + +//We check if this user can go in the given network +int allow_roaming(const unsigned char *username, const size_t usernamelen, const char * network,const size_t networklen) +{ + CHECK_PARAMS(username && usernamelen && network && networklen); + + int not_found=2; + size_t querylen, usernamepurelen; + char *query, *username_pure; + + switch(as_conf->datasource) + { + //MySQL + case ASMYSQL: + //We allocate the double size of username because at worst it can be all quotes + username_pure=malloc(usernamelen*2+1); + //We purify username not to have forbidden characters + usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen); + + //We get the list of AOR owned by this user + querylen=SQL_GETUSERNET_LEN + usernamepurelen; + query = malloc(querylen+2); + snprintf(query, querylen+1, SQL_GETUSERNET, username_pure); + + + MYSQL_RES *res; + MYSQL_ROW row; + + + //We make the query + request_mysql(query); + res=mysql_use_result(conn); + if(res==NULL) + { + free(query); + return 2; + } + + + not_found=1; + while ((row = mysql_fetch_row(res)) != NULL) + { + if(strncmp((const char *)network,row[0],networklen)==0) + { + not_found=0; + break; + } + } + mysql_free_result(res); + free(query); + break; + } + return not_found; +} + +//SIP-Server-Capabilities for the SIP-AOR +int get_sipserver_cap(const unsigned char *sip_aor, const size_t sipaorlen, struct avp **capabilities) +{ + CHECK_PARAMS(sip_aor && sipaorlen && capabilities); + + size_t querylen, sipaorpurelen; + char *query, *sipaor_pure; + int not_found=2; + union avp_value value; + struct avp *avp; + + //a sip aor must begin by "sip:" or "sips:" so it must at least be longer than 4 chars + if(sipaorlen<5) + return 2; + + //NOTE: each method has to purify sip_aor itself. You must remove quotes or special chars for security + switch(as_conf->datasource) + { + //MySQL + case ASMYSQL: + + querylen=SQL_GETSIPSERCAP_LEN + sipaorlen; + + + //We allocate the double size of SIP-URI because at worst it can be all quotes + CHECK_MALLOC(sipaor_pure=malloc(sipaorlen*2+1)); + //We purify SIP-URI not to have forbidden characters + sipaorpurelen=mysql_real_escape_string(conn, sipaor_pure, (const char *)sip_aor, sipaorlen); + + + query = malloc(querylen+sipaorpurelen+ 2); + snprintf(query, querylen+1, SQL_GETSIPSERCAP, sipaor_pure); + + MYSQL_RES *res; + MYSQL_ROW row; + + //We make the query + request_mysql(query); + res=mysql_use_result(conn); + if(res==NULL) + { + //We couldn't make the request + return 2; + } + not_found=1; + while ((row = mysql_fetch_row(res)) != NULL) + { + if(atoi(row[0])==1) + {//mandatory + CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Mandatory_Capability, 0, &avp ) ); + value.i32=(uint32_t)atoi(row[1]); + CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add ( *capabilities, MSG_BRW_LAST_CHILD, avp) ); + + } + else + {//optional + CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Optional_Capability, 0, &avp ) ); + value.i32=(uint32_t)atoi(row[1]); + CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add ( *capabilities, MSG_BRW_LAST_CHILD, avp) ); + } + not_found=0; + } + + mysql_free_result(res); + free(query); + free(sipaor_pure); + break; + + default: + + //We must never go here, if so, we must stop diameter_sip + TRACE_DEBUG(INFO,"FATAL ERROR: the datasource is unknown, please check your config file!"); + return 2; + + break; + } + + //0 if it was found + return not_found; + +} + + +//We retrieve datatype +int get_user_datatype(const unsigned char *username, const size_t usernamelen, char **table_supported, const int num_elements, struct avp **groupedavp) +{ + CHECK_PARAMS(table_supported && num_elements && username && usernamelen && groupedavp); + + + int counter=0, not_found=1; + union avp_value value; + struct avp *avp, *rootavp; + size_t querylen, usernamepurelen; + char *query, *username_pure; + + if(num_elements<1) + return 1; + + //NOTE: each method has to purify sip_aor itself. You must remove quotes or special chars for security + switch(as_conf->datasource) + { + //MySQL + case ASMYSQL: + + querylen=SQL_GETUSEDATA_LEN + usernamelen; + + + //We allocate the double size of username because at worst it can be all quotes + username_pure=malloc(usernamelen*2+1); + //We purify username not to have forbidden characters + usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen); + + + query = malloc(querylen+usernamelen+ 2); + snprintf(query, querylen+1, SQL_GETUSEDATA, username_pure); + + MYSQL_RES *res; + MYSQL_ROW row; + + //We make the query + request_mysql(query); + res=mysql_use_result(conn); + if(res==NULL) + { + //We couldn't make the request + return 2; + } + not_found=1; + + counter=0; + unsigned long *length=0; + + //int index=0;//current field number + + while ((row = mysql_fetch_row(res)) != NULL) + { + length=mysql_fetch_lengths(res); + + for(counter=0;counterdatasource) + { + //MySQL + case ASMYSQL: + //We allocate the double size of username because at worst it can be all quotes + username_pure=malloc(usernamelen*2+1); + //We purify username not to have forbidden characters + usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen); + + + + //We clear the flag "authentication pending" + querylen=SQL_SETFLAG_LEN + usernamepurelen; + query = malloc(querylen+2); + snprintf(query, querylen+1, SQL_SETFLAG, username_pure); + + if (mysql_query(conn, query)) + { + TRACE_DEBUG(INFO,"Query %s failed", query); + free(query); + return 2; + } + + free(query); + break; + } + return 0; +} +int clear_pending_flag(const unsigned char *username, const size_t usernamelen) +{ + CHECK_PARAMS(username && usernamelen); + + int not_found=2; + size_t querylen, usernamepurelen; + char *query, *username_pure; + + switch(as_conf->datasource) + { + //MySQL + case ASMYSQL: + //We allocate the double size of username because at worst it can be all quotes + username_pure=malloc(usernamelen*2+1); + //We purify username not to have forbidden characters + usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen); + + + + //We clear the flag "authentication pending" + querylen=SQL_CLEARFLAG_LEN + usernamepurelen; + query = malloc(querylen+2); + snprintf(query, querylen+1, SQL_CLEARFLAG, username_pure); + + if (mysql_query(conn, query)) + { + TRACE_DEBUG(INFO,"Query %s failed", query); + free(query); + return 2; + } + + free(query); + break; + } + return 0; +} + + + +int set_sipserver_uri(const unsigned char *username, const size_t usernamelen, const unsigned char *sipserver_uri,const size_t sipserverurilen) +{ + CHECK_PARAMS(username && usernamelen && sipserver_uri && sipserverurilen); + + int not_found=2; + size_t querylen, usernamepurelen, sipserveruripurelen; + char *query, *username_pure, *sipserveruri_pure; + + switch(as_conf->datasource) + { + //MySQL + case ASMYSQL: + //We allocate the double size of username because at worst it can be all quotes + username_pure=malloc(usernamelen*2+1); + //We purify username not to have forbidden characters + usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen); + + //We allocate the double size of username because at worst it can be all quotes + sipserveruri_pure=malloc(sipserverurilen*2+1); + //We purify username not to have forbidden characters + sipserveruripurelen=mysql_real_escape_string(conn, sipserveruri_pure, (const char *)sipserver_uri, sipserverurilen); + + //We clear the flag "authentication pending" + querylen=SQL_SETSIPURI_LEN + usernamepurelen + sipserveruripurelen; + query = malloc(querylen+2); + snprintf(query, querylen+1, SQL_SETSIPURI, sipserveruri_pure,username_pure); + + if (mysql_query(conn, query)) + { + TRACE_DEBUG(INFO,"Query %s failed", query); + free(query); + return 2; + } + + free(query); + break; + } + return 0; +} +int remove_sipserver_uri(const unsigned char *sipserver_uri,const size_t sipserverurilen) +{ + CHECK_PARAMS(sipserver_uri && sipserverurilen); + + int not_found=2; + size_t querylen, sipserveruripurelen; + char *query, *sipserveruri_pure; + + switch(as_conf->datasource) + { + //MySQL + case ASMYSQL: + //We allocate the double size of username because at worst it can be all quotes + sipserveruri_pure=malloc(sipserverurilen*2+1); + //We purify username not to have forbidden characters + sipserveruripurelen=mysql_real_escape_string(conn, sipserveruri_pure, (const char *)sipserver_uri, sipserverurilen); + + //We clear the flag "authentication pending" + querylen=SQL_RMSIPURI_LEN + sipserveruripurelen; + query = malloc(querylen+2); + snprintf(query, querylen+1, SQL_RMSIPURI, sipserveruri_pure); + + if (mysql_query(conn, query)) + { + TRACE_DEBUG(INFO,"Query %s failed", query); + free(query); + return 2; + } + + free(query); + break; + } + return 0; +} +int set_real_sipserver_uri(const unsigned char *username, const size_t usernamelen, const unsigned char *sipserver_uri,const size_t sipserverurilen) +{ + CHECK_PARAMS(username && usernamelen && sipserver_uri && sipserverurilen); + + int not_found=2; + size_t querylen, usernamepurelen, sipserveruripurelen; + char *query, *username_pure, *sipserveruri_pure; + + switch(as_conf->datasource) + { + //MySQL + case ASMYSQL: + //We allocate the double size of username because at worst it can be all quotes + username_pure=malloc(usernamelen*2+1); + //We purify username not to have forbidden characters + usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen); + + //We allocate the double size of username because at worst it can be all quotes + sipserveruri_pure=malloc(sipserverurilen*2+1); + //We purify username not to have forbidden characters + sipserveruripurelen=mysql_real_escape_string(conn, sipserveruri_pure, (const char *)sipserver_uri, sipserverurilen); + + //We clear the flag "authentication pending" + querylen=SQL_SETREALSIPURI_LEN + usernamepurelen + sipserveruripurelen; + query = malloc(querylen+2); + snprintf(query, querylen+1, SQL_SETREALSIPURI, sipserveruri_pure,username_pure); + + if (mysql_query(conn, query)) + { + TRACE_DEBUG(INFO,"Query %s failed", query); + free(query); + return 2; + } + + free(query); + break; + } + return 0; +} + +int get_sipserver_uri(const unsigned char *sip_aor, const size_t sipaorlen, char ** sipserver_uri, size_t *sipserverurilen) +{ + CHECK_PARAMS(sip_aor && sipaorlen && sipserver_uri && sipserverurilen ); + + size_t querylen, sipaorpurelen; + char *query, *sipaor_pure; + int not_found=2; + + + + + //a sip aor must begin by "sip:" or "sips:" so it must at least be longer than 4 chars + if(sipaorlen<5) + return 2; + + //NOTE: each method has to purify sip_aor itself. You must remove quotes or special chars for security + + switch(as_conf->datasource) + { + //MySQL + case ASMYSQL: + + querylen=SQL_GETSIPSERURI_LEN + sipaorlen; + + //We allocate the double size of SIP-URI because at worst it can be all quotes + CHECK_MALLOC(sipaor_pure=malloc(sipaorlen*2+1)); + //We purify SIP-URI not to have forbidden characters + sipaorpurelen=mysql_real_escape_string(conn, sipaor_pure, (const char *)sip_aor, sipaorlen); + + + query = malloc(querylen+sipaorpurelen+ 2); + snprintf(query, querylen+1, SQL_GETSIPSERURI, sipaor_pure); + + MYSQL_RES *res; + MYSQL_ROW row; + + //We make the query + request_mysql(query); + res=mysql_use_result(conn); + if(res==NULL) + { + //We couldn't make the request + sipserver_uri=NULL; + return 2; + } + + not_found=1; + while ((row = mysql_fetch_row(res)) != NULL) + { + *sipserverurilen=strlen(row[0]); + if(*sipserverurilen>4) + { + CHECK_MALLOC(*sipserver_uri=malloc(*sipserverurilen+1)); + strcpy(*sipserver_uri,row[0]); + not_found=0; + break; + } + } + mysql_free_result(res); + free(query); + free(sipaor_pure); + break; + + default: + + //We must never go here, if so, we must stop diameter_sip + TRACE_DEBUG(INFO,"FATAL ERROR: the datasource is unknown, please check your config file!"); + sipserver_uri=NULL; + return 2; + + break; + } + + //0 if it was found + return not_found; + +} + +int count_sipaor(const struct msg * message) +{ + CHECK_PARAMS(message); + + struct avp_hdr *temphdr; + struct avp *avp; + int counter=0; + + CHECK_FCT(fd_msg_browse ( &message, MSG_BRW_WALK, &avp, NULL)); + + while(avp!=NULL) + { + + CHECK_FCT( fd_msg_avp_hdr( avp,&temphdr )); + + if(temphdr->avp_code==122 && temphdr->avp_vendor==0) + { + counter++; + } + + CHECK_FCT(fd_msg_browse ( &message, MSG_BRW_WALK, &avp, NULL)); + } + return counter; +} +int count_supporteddatatype(const struct msg * message) +{ + CHECK_PARAMS(message); + + struct avp_hdr *temphdr; + struct avp *avp; + int counter=0; + + CHECK_FCT(fd_msg_browse ( &message, MSG_BRW_WALK, &avp, NULL)); + + while(avp!=NULL) + { + + CHECK_FCT( fd_msg_avp_hdr( avp,&temphdr )); + + if(temphdr->avp_code==388 && temphdr->avp_vendor==0) + { + counter++; + } + + CHECK_FCT(fd_msg_browse ( &message, MSG_BRW_WALK, &avp, NULL)); + } + return counter; +} /* void nonce_add_element(char * nonce) { diff -r 44541db912a2 -r 3d9f300f3b49 extensions/app_sip/locationinfo.c --- a/extensions/app_sip/locationinfo.c Mon Jul 26 18:33:50 2010 +0900 +++ b/extensions/app_sip/locationinfo.c Mon Jul 26 21:39:27 2010 +0900 @@ -44,6 +44,7 @@ struct avp *avp, *groupedavp; struct avp_hdr *avphdr; union avp_value value; + int ret=0; //Result_Code to return in the answer char result[55]; @@ -57,6 +58,13 @@ 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 { @@ -68,32 +76,122 @@ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) ); } - //TODO: wait for answer from authors to clear how to find SIP server! + //Add a SIP_Server_URI { CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_AOR, &avp) ); CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) ); - //We extract Realm from SIP_AOR - char *realm=NULL; + + + + + ret=exist_username(avphdr->avp_value->os.data, avphdr->avp_value->os.len); + + + if(ret==2) + {//error + /* + If the Diameter server cannot process the Diameter LIR command, e.g., + due to a database error, the Diameter server MUST set the Result-Code + AVP value to DIAMETER_UNABLE_TO_COMPLY and return it in a Diameter + LIA message. + */ + strcpy(result,"DIAMETER_UNABLE_TO_COMPLY"); + goto out; + } + else if(ret==1) + {//not found + /* + One of the errors that the Diameter server may find is that the + SIP-AOR AVP value is not a valid user in the realm. In such cases, + the Diameter server MUST set the Result-Code AVP value to + DIAMETER_ERROR_USER_UNKNOWN and return it in a Diameter LIA message. + + */ + strcpy(result,"DIAMETER_ERROR_USER_UNKNOWN"); + goto out; + } + + //If we arrive here, the user is known + int sipserverurilen; + char * sipserver_uri=NULL; + + ret=get_sipserver_uri(avphdr->avp_value->os.data, avphdr->avp_value->os.len, &sipserver_uri, &sipserverurilen); - realm = strtok( (char *)(avphdr->avp_value->os.data), "@" ); - realm = strtok( NULL, "@" ); + if(ret==0) + {//found + if(sipserver_uri==NULL) + { + //There is a problem because we must get a Diameter_URI here + strcpy(result,"DIAMETER_UNABLE_TO_COMPLY"); + goto out; + } + else + { + CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Server_URI, 0, &avp ) ); + value.os.data=(unsigned char *)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) ); + + strcpy(result,"DIAMETER_SUCCESS"); + } + } + else if(ret==1) + {//not found + //We don't know this SIP_AOR in SL, that means + strcpy(result,"DIAMETER_ERROR_USER_UNKNOWN"); + goto out; + } + else + {// returned 2, impossible to make request + //We couldn't make the request, we must stop process! + strcpy(result,"DIAMETER_UNABLE_TO_COMPLY"); + goto out; + } - if(realm!=NULL) + //Adding SIP-Server-Capabilities + CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Server_Capabilities, 0, &groupedavp ) ); + //We add mandatory and optional capabilities + ret=get_sipserver_cap(avphdr->avp_value->os.data, avphdr->avp_value->os.len, &groupedavp); + + + if(ret==0) + {//found + if(sipserver_uri==NULL) { - CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Server_URI, 0, &avp ) ); - value.os.data=(unsigned char *)realm; - value.os.len=strlen(realm); - CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); - CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, avp) ); + //There is a problem because we must get a Diameter_URI here + strcpy(result,"DIAMETER_UNABLE_TO_COMPLY"); + CHECK_FCT( fd_msg_free( groupedavp ) ); + goto out; } else { - strcpy(result,"DIAMETER_UNABLE_TO_COMPLY"); + + CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, groupedavp) ); + + strcpy(result,"DIAMETER_SUCCESS"); + } + } + else if(ret==1) + {//not found + //We don't know this SIP_AOR in SL, that means + strcpy(result,"DIAMETER_ERROR_IDENTITY_NOT_REGISTERED"); + CHECK_FCT( fd_msg_free( groupedavp ) ); goto out; } + else + {// returned 2, impossible to make request + //We couldn't make the request, we must stop process! + strcpy(result,"DIAMETER_UNABLE_TO_COMPLY"); + CHECK_FCT( fd_msg_free( groupedavp ) ); + goto out; + } + + + } diff -r 44541db912a2 -r 3d9f300f3b49 extensions/app_sip/locationinfosl.c --- a/extensions/app_sip/locationinfosl.c Mon Jul 26 18:33:50 2010 +0900 +++ b/extensions/app_sip/locationinfosl.c Mon Jul 26 21:39:27 2010 +0900 @@ -60,8 +60,6 @@ CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) ); ans = *msg; - //DEBUG - fd_msg_dump_walk(INFO,qry); //Add the Auth-Application-Id { @@ -90,7 +88,7 @@ int diameterurilen; char * diameter_uri=NULL; - TRACE_DEBUG(INFO,"***********%d*********************************************",avphdr->avp_value->os.len); + ret=get_diameter_uri(avphdr->avp_value->os.data, avphdr->avp_value->os.len, &diameter_uri, &diameterurilen); @@ -107,7 +105,7 @@ { CHECK_FCT( fd_msg_avp_new ( sip_dict.Redirect_Host, 0, &avp ) ); value.os.data=diameter_uri; - value.os.len=strlen(diameter_uri); + value.os.len=diameterurilen; CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) ); @@ -120,7 +118,7 @@ } else if(ret==1) {//not found - //We don't know this SIP_AOR in SL, that means + //We don't know this SIP_AOR in SL strcpy(result,"DIAMETER_ERROR_USER_UNKNOWN"); goto out; } @@ -132,37 +130,6 @@ } } - /* - //TODO: wait for answer from authors to clear how to find SIP server! - //Add a SIP_Server_URI - { - CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_AOR, &avp) ); - CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) ); - - //We extract Realm from SIP_AOR - char *realm=NULL; - - - realm = strtok( (char *)(avphdr->avp_value->os.data), "@" ); - realm = strtok( NULL, "@" ); - - if(realm!=NULL) - { - CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Server_URI, 0, &avp ) ); - value.os.data=(unsigned char *)realm; - value.os.len=strlen(realm); - CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); - CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, avp) ); - } - else - { - strcpy(result,"DIAMETER_UNABLE_TO_COMPLY"); - goto out; - } - } - - */ - out: CHECK_FCT( fd_msg_rescode_set( ans, result, NULL, NULL, 1 ) ); diff -r 44541db912a2 -r 3d9f300f3b49 extensions/app_sip/multimediaauth.c --- a/extensions/app_sip/multimediaauth.c Mon Jul 26 18:33:50 2010 +0900 +++ b/extensions/app_sip/multimediaauth.c Mon Jul 26 21:39:27 2010 +0900 @@ -47,7 +47,7 @@ struct avp * tempavp=NULL,*sipAuthentication=NULL,*sipAuthenticate=NULL; char * result; char password[51]; - int idx=0, number_of_auth_items=0,i=0; + int idx=0, number_of_auth_items=0,i=0, ret=0; //Flags and variables for Database int sipurinotstored=0, authenticationpending=0, querylen=0, usernamelen=0; char *query=NULL,*username=NULL; @@ -121,48 +121,25 @@ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) ); - //We allocate the double size of username because at worst it can be all quotes - username=malloc(avphdr->avp_value->os.len*2+1); - //We purify username not to have forbidden characters - usernamelen=mysql_real_escape_string(conn, username, (const char *)avphdr->avp_value->os.data, avphdr->avp_value->os.len); + if((strncmp((const char *)avpheader->avp_value->os.data,"REGISTER",avpheader->avp_value->os.len)==0)) { not_found=1; - //We copy username in query - querylen=SQL_GETPASSWORD_LEN + usernamelen; - query = malloc(querylen+2); - snprintf(query, querylen+1, SQL_GETPASSWORD, username); - + //TODO TODO TODO TODO TODO TODO TODO: maybe doesn't work!!' + ret=get_password(avphdr->avp_value->os.data, avphdr->avp_value->os.len, (char *)&password); - - //We make the query - request_mysql(query); - res=mysql_use_result(conn); - if(res==NULL) + if(ret>1) { //We couldn't make the request result="DIAMETER_UNABLE_TO_COMPLY"; goto out; } - - - - while ((row = mysql_fetch_row(res)) != NULL) - { - if(strlen(row[0])>0) - { - strcpy(password,row[0]); - not_found=0; - break; - } - } - mysql_free_result(res); - free(query); - - if(not_found) + not_found=ret; + + if(not_found) { TRACE_DEBUG(FULL,"The user %s doesn't exist!",username); result="DIAMETER_ERROR_USER_UNKNOWN"; @@ -171,7 +148,11 @@ } - + //We allocate the double size of username because at worst it can be all quotes + username=malloc(avphdr->avp_value->os.len*2+1); + //We purify username not to have forbidden characters + usernamelen=mysql_real_escape_string(conn, username, (const char *)avphdr->avp_value->os.data, avphdr->avp_value->os.len); + //Now that we know the user exist, we get the list of AOR owned by this user querylen=SQL_GETSIPAOR_LEN + usernamelen; query = malloc(querylen+2); @@ -193,17 +174,17 @@ not_found=1; while ((row = mysql_fetch_row(res)) != NULL) - { - if(strncmp((const char *)avphdr->avp_value->os.data,row[0],avphdr->avp_value->os.len)==0) - { - not_found=0; - break; - } - } - mysql_free_result(res); - free(query); + { + if(strncmp((const char *)avphdr->avp_value->os.data,row[0],avphdr->avp_value->os.len)==0) + { + not_found=0; + break; + } + } + mysql_free_result(res); + free(query); - if(not_found) + if(not_found) { TRACE_DEBUG(FULL,"The user %s can't use this SIP-AOR!",username); result="DIAMETER_ERROR_IDENTITIES_DONT_MATCH"; @@ -243,30 +224,28 @@ } not_found=1; while ((row = mysql_fetch_row(res)) != NULL) - { - if(strncmp((const char *)avphdr->avp_value->os.data,row[0],avphdr->avp_value->os.len)==0) - { - not_found=0; - break; - } - } - mysql_free_result(res); - free(query); - - if(not_found) { - //We update the SIP_URI for the user and we flag "authentication in progress" - querylen=SQL_SETSIPURI_LEN + usernamelen + sipurilen; - query = malloc(querylen+2); - snprintf(query, querylen+1, SQL_SETSIPURI, sipuri, username); - - //We make the query - request_mysql(query); + if(strncmp((const char *)avphdr->avp_value->os.data,row[0],avphdr->avp_value->os.len)==0) + { + not_found=0; + break; + } + } + mysql_free_result(res); + free(query); + + if(not_found) + { + //Temporary + set_sipserver_uri(username, usernamelen, sipuri,sipurilen); - free(query); - authenticationpending=1; + + set_pending_flag(username, usernamelen); + + + authenticationpending=1; } - free(sipuri); + free(sipuri); } else @@ -714,15 +693,8 @@ if(username!=NULL && authenticationpending) { - //We clear the flag "authentication pending" - querylen=SQL_CLEARFLAG_LEN + usernamelen; - query = malloc(querylen+2); - snprintf(query, querylen+1, SQL_CLEARFLAG, username); - - //We make the query - request_mysql(query); - - free(query); + //We clear the pending flag + clear_pending_flag(username, usernamelen); } if(sipurinotstored) diff -r 44541db912a2 -r 3d9f300f3b49 extensions/app_sip/serverassignment.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extensions/app_sip/serverassignment.c Mon Jul 26 21:39:27 2010 +0900 @@ -0,0 +1,461 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Alexandre Westfahl * +* * +* 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 "diamsip.h" + + +int diamsip_SAR_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, 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, *usernamehdr, *sipuserdataalreadyavailable; + union avp_value value; + int ret=0, assignment_type=0, supported_datatype=0, got_datatype=0; + + + struct listdatatype + { + struct fd_list datatype; + char * type; + size_t typelen; + }; + + //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) ); + if(avp!=NULL) + { + CHECK_FCT( fd_msg_avp_hdr( avp, &sipaorhdr ) ); + } + else + sipaorhdr=NULL; + + } + + //We check if we have a username 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 + + if(sipaorhdr!=NULL) + { + //We must check that this user can use this SIP-AOR + ret=check_sipaor(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len, sipaorhdr->avp_value->os.data,sipaorhdr->avp_value->os.len); + + if(ret==0) + { + //The SIP-AOR and Username are ok! + ret=clear_pending_flag(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len); + if(ret==2) + { + TRACE_DEBUG(INFO,"ERROR: We couldn't clear the flag of pending authentication.'"); + strcpy(result,"DIAMETER_UNABLE_TO_COMPLY"); + goto out; + } + } + 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; + } + } + else + { + TRACE_DEBUG(INFO,"ERROR: There is no SIP-AOR AVP!'"); + strcpy(result,"DIAMETER_ERROR_IDENTITIES_DONT_MATCH"); + goto out; + } + } + } + else + { + if(sipaorhdr!=NULL) + {//If we have a SIP-AOR, we want the user to check it. + strcpy(result,"DIAMETER_USER_NAME_REQUIRED"); + goto out; + } + usernamehdr=NULL; + } + + } + + //We get the SIP_Server_Assignment_Type + { + CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Server_Assignment_Type, &avp) ); + CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) ); + + assignment_type=avphdr->avp_value->i32; + } + + //TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO : check which assignment need data type + //We check if we have SIP_Supported_User_Data_Type and we make a table with all of them + { + supported_datatype=count_supporteddatatype(qry); + + if(supported_datatype>0) + { + char ** table_supporteddatatype=NULL; + + //TODO: maybe table doesn't work' + //We make a table of char * to store all supported datatypes + CHECK_MALLOC(table_supporteddatatype=(char**)realloc(table_supporteddatatype,supported_datatype*sizeof(char *))); + + + CHECK_FCT(fd_msg_browse ( qry, MSG_BRW_WALK, &avp, NULL)); + int counter=0; + + while(avp!=NULL) + { + + CHECK_FCT( fd_msg_avp_hdr( avp,&avphdr )); + + //TODO: check if counter is good! + if(avphdr->avp_code==388 && avphdr->avp_vendor==0 && counteravp_value->os.len+1)); + strncpy(table_supporteddatatype[counter],avphdr->avp_value->os.data,avphdr->avp_value->os.len); + table_supporteddatatype[counter][avphdr->avp_value->os.len+1]='\0'; + + counter++; + } + + CHECK_FCT(fd_msg_browse ( qry, MSG_BRW_WALK, &avp, NULL)); + } + + if(usernamehdr!=NULL) + { + ret=get_user_datatype(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len,(char **)table_supporteddatatype, counter, &groupedavp); + + //We free all unused datatypes + int i=0; + for(i=0;iavp_value->i32==0) + {//Data not available, we must provide it + if(got_datatype==1) + { + //We provide User Data + CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, groupedavp) ); + } + } + strcpy(result,"DIAMETER_SUCCESS"); + goto out; + } + else + {//There is more than 1 SIP-AOR AVP + strcpy(result,"DIAMETER_AVP_OCCURS_TOO_MANY_TIMES"); + goto out; + } + } + else if(assignment_type==3) + {//Unregistered user + + //TODO:place user unknown here! + if(count_sipaor(qry)==1) + { + if(sipuserdataalreadyavailable->avp_value->i32==0) + {//Data not available, we must provide it + if(got_datatype==1) + { + //We provide User Data + CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, groupedavp) ); + } + } + strcpy(result,"DIAMETER_SUCCESS"); + goto out; + } + else + {//There is more than 1 SIP-AOR AVP + strcpy(result,"DIAMETER_AVP_OCCURS_TOO_MANY_TIMES"); + goto out; + } + + if(sipuserdataalreadyavailable->avp_value->i32==0) + {//Data not available, we must provide it + if(got_datatype==1) + { + //We provide User Data + CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, groupedavp) ); + } + } + + CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Server_URI, &avp) ); + if(avp!=NULL) + { + CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr )); + + set_real_sipserver_uri(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len, avphdr->avp_value->os.data,avphdr->avp_value->os.len); + strcpy(result,"DIAMETER_SUCCESS"); + goto out; + } + else + { + TRACE_DEBUG(INFO,"There is no SIP_Server_URI AVP in this Unregistered User Request!"); + strcpy(result,"DIAMETER_UNABLE_TO_COMPLY"); + goto out; + } + } + else if(assignment_type==4 || assignment_type==5 || assignment_type==11 || assignment_type==8) + {//Unregistered user + + if(got_datatype==1) + { + if(sipuserdataalreadyavailable->avp_value->i32==0) + {//Data not available, we must provide it + + //We provide User Data + CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, groupedavp) ); + } + else + { + CHECK_FCT( fd_msg_free( groupedavp ) ); + } + } + + if(sipaorhdr==NULL) + { + //We don't have any SIP-AOR to unregister, this is strange!' + TRACE_DEBUG(INFO, "There was no SIP-AOR in this request, we can't proceed request!'"); + strcpy(result,"DIAMETER_UNABLE_TO_COMPLY"); + goto out; + } + else + { + //TODO: unregister SIP-Server-URI for all SIP-AOR + } + strcpy(result,"DIAMETER_SUCCESS"); + goto out; + } + else if(assignment_type==6 || assignment_type==7) + { + + + CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Server_URI, &avp) ); + if(avp!=NULL) + { + CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr )); + + //TODO: set SIP server URI for each AOR + + //TODO: unregister all SIP-AOR provided + + //set_real_sipserver_uri(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len, avphdr->avp_value->os.data,avphdr->avp_value->os.len); + strcpy(result,"DIAMETER_SUCCESS"); + goto out; + } + else + { + + + //TODO: unregister all SIP-AOR provided + + //TODO: clear sip server uri in database for the sip-aor + + + TRACE_DEBUG(INFO,"There is no SIP_Server_URI AVP in this Deregistration User Request! We just unregister SIP-AOR"); + strcpy(result,"DIAMETER_SUCCESS_SERVER_NAME_NOT_STORED"); + goto out; + } + } + else if(assignment_type==0) + { + + + CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Server_URI, &avp) ); + if(avp!=NULL) + { + //TODO: check that SIP-server_URI provided is the same as associated and answer unable to comply if so + //TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO here + + + CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr )); + + if(got_datatype==1) + { + if(sipuserdataalreadyavailable->avp_value->i32==0) + {//Data not available, we must provide it + + //We provide User Data + CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, groupedavp) ); + } + else + { + CHECK_FCT( fd_msg_free( groupedavp ) ); + } + } + + + + + //set_real_sipserver_uri(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len, avphdr->avp_value->os.data,avphdr->avp_value->os.len); + strcpy(result,"DIAMETER_SUCCESS"); + goto out; + } + else + { + TRACE_DEBUG(INFO, "There was no SIP-AOR in this request, we can't proceed request!'"); + strcpy(result,"DIAMETER_UNABLE_TO_COMPLY"); + goto out; + } + } + else if(assignment_type==9 || assignment_type==10) + { + if(count_sipaor(qry)==1) + { + //TODO: remove SIP-server URI for sip_aor + //TODO: unregister it + strcpy(result,"DIAMETER_SUCCESS"); + goto out; + } + else + {//There is more than 1 SIP-AOR AVP + strcpy(result,"DIAMETER_AVP_OCCURS_TOO_MANY_TIMES"); + 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; +} diff -r 44541db912a2 -r 3d9f300f3b49 extensions/app_sip/userauthorization.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extensions/app_sip/userauthorization.c Mon Jul 26 21:39:27 2010 +0900 @@ -0,0 +1,337 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Alexandre Westfahl * +* * +* 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 "diamsip.h" + + +int diamsip_UAR_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, 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, 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, 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' + 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; +} diff -r 44541db912a2 -r 3d9f300f3b49 extensions/test_sip/CMakeLists.txt --- a/extensions/test_sip/CMakeLists.txt Mon Jul 26 18:33:50 2010 +0900 +++ b/extensions/test_sip/CMakeLists.txt Mon Jul 26 21:39:27 2010 +0900 @@ -10,7 +10,10 @@ test_sip.h multimediaauth.c locationinfo.c + locationinfosl.c registrationtermination.c + userauthorization.c + serverassignment.c ) # Compile as a module diff -r 44541db912a2 -r 3d9f300f3b49 extensions/test_sip/locationinfo.c --- a/extensions/test_sip/locationinfo.c Mon Jul 26 18:33:50 2010 +0900 +++ b/extensions/test_sip/locationinfo.c Mon Jul 26 21:39:27 2010 +0900 @@ -49,7 +49,7 @@ size_t aor_len=strlen(sip_aor); char *destination_realm="tera.ics.keio.ac.jp"; size_t destination_realmlen=strlen(destination_realm); - char *destination_host="biwa.tera.ics.keio.ac.jp"; + char *destination_host="suika.tera.ics.keio.ac.jp"; size_t destination_hostlen=strlen(destination_host); //Fake values STOP @@ -107,8 +107,6 @@ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); } - - //SIP_AOR { diff -r 44541db912a2 -r 3d9f300f3b49 extensions/test_sip/locationinfosl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extensions/test_sip/locationinfosl.c Mon Jul 26 21:39:27 2010 +0900 @@ -0,0 +1,133 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Alexandre Westfahl * +* * +* 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 "test_sip.h" + +//Called to send a LIR +int test_sipSL_LIR_cb() +{ + struct dict_object * lir_model=NULL; + struct msg * message=NULL; + struct avp *avp=NULL; + struct session *sess=NULL; + union avp_value value; + + //Fake values START + unsigned char *sip_aor="sip:aw-lappy@tera.ics.keio.ac.jp"; + size_t aor_len=strlen(sip_aor); + char *destination_realm="tera.ics.keio.ac.jp"; + size_t destination_realmlen=strlen(destination_realm); + char *destination_host="biwa.tera.ics.keio.ac.jp"; + size_t destination_hostlen=strlen(destination_host); + //Fake values STOP + + //Create the base message for an RTR + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Location-Info-Request", &lir_model, ENOENT) ); + CHECK_FCT( fd_msg_new (lir_model, 0, &message)); + + + + // Create a new session + { + CHECK_FCT( fd_sess_new( &sess, fd_g_config->cnf_diamid, "appsip", 6 )); + char * sid; + CHECK_FCT( fd_sess_getsid ( sess, &sid )); + CHECK_FCT( fd_msg_avp_new ( sip_dict.Session_Id, 0, &avp )); + value.os.data = (uint8_t *)sid; + value.os.len = strlen(sid); + CHECK_FCT( fd_msg_avp_setvalue( avp, &value )); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp )); + } + + //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 ( message, MSG_BRW_LAST_CHILD, avp) ); + } + + //Auth_Session_State + { + CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) ); + value.i32=1; + CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); + } + + //Origin_Host & Origin_Realm + CHECK_FCT( fd_msg_add_origin ( message, 0 )); + + //Destination_Host + { + CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Host, 0, &avp ) ); + value.os.data=(unsigned char *)destination_host; + value.os.len=destination_hostlen; + CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); + } + //Destination_Realm + { + CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Realm, 0, &avp ) ); + value.os.data=(unsigned char *)destination_realm; + value.os.len=destination_realmlen; + CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); + } + + + + //SIP_AOR + { + + CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) ); + value.os.data=sip_aor; + value.os.len=aor_len; + CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); + + } + + fd_msg_dump_walk(INFO,message); + CHECK_FCT( fd_msg_send( &message, NULL, NULL )); + + return 0; +} + +int test_sipSL_LIA_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, enum disp_action * act) +{ + + return 0; +} diff -r 44541db912a2 -r 3d9f300f3b49 extensions/test_sip/serverassignment.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extensions/test_sip/serverassignment.c Mon Jul 26 21:39:27 2010 +0900 @@ -0,0 +1,162 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Alexandre Westfahl * +* * +* 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 "test_sip.h" + +//Called to send a UAR +int test_sip_SAR_cb() +{ + struct dict_object * sar_model=NULL; + struct msg * message=NULL; + struct avp *avp=NULL; + struct session *sess=NULL; + union avp_value value; + + //Fake values START + unsigned char *sip_aor="sip:aw-lappy@tera.ics.keio.ac.jp"; + size_t aor_len=strlen(sip_aor); + unsigned char *destination_realm="tera.ics.keio.ac.jp"; + size_t destination_realmlen=strlen(destination_realm); + unsigned char *destination_host="suika.tera.ics.keio.ac.jp"; + size_t destination_hostlen=strlen(destination_host); + unsigned char *username="aw-lappy"; + size_t usernamelen=strlen(username); + unsigned char *visitednetwork="Pink"; + size_t visitednetworklen=strlen(visitednetwork); + int registrationtype = 2; + int data_already_available=0; + int assignment_type=0; + //Fake values STOP + + //Create the base message for an RTR + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Server-Assignment-Request", &sar_model, ENOENT) ); + CHECK_FCT( fd_msg_new (sar_model, 0, &message)); + + + + // Create a new session + { + CHECK_FCT( fd_sess_new( &sess, fd_g_config->cnf_diamid, "appsip", 6 )); + char * sid; + CHECK_FCT( fd_sess_getsid ( sess, &sid )); + CHECK_FCT( fd_msg_avp_new ( sip_dict.Session_Id, 0, &avp )); + value.os.data = (uint8_t *)sid; + value.os.len = strlen(sid); + CHECK_FCT( fd_msg_avp_setvalue( avp, &value )); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp )); + } + + //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 ( message, MSG_BRW_LAST_CHILD, avp) ); + } + //Auth_Session_State + { + CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) ); + value.i32=1; + CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); + } + + //Origin_Host & Origin_Realm + CHECK_FCT( fd_msg_add_origin ( message, 0 )); + + //Destination_Host + { + CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Host, 0, &avp ) ); + value.os.data=destination_host; + value.os.len=destination_hostlen; + CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); + } + //Destination_Realm + { + CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Realm, 0, &avp ) ); + value.os.data=destination_realm; + value.os.len=destination_realmlen; + CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); + } + + //SIP_AOR + { + + CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) ); + value.os.data=sip_aor; + value.os.len=aor_len; + CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); + + } + //Username + { + + CHECK_FCT( fd_msg_avp_new ( sip_dict.User_Name, 0, &avp ) ); + value.os.data=username; + value.os.len=usernamelen; + CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); + + } + //SIP_User_Data_Already_Available + { + CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_User_Data_Already_Available, 0, &avp ) ); + value.i32=data_already_available; + CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); + } + + //SIP_Server_Assignment_Type; + { + CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Server_Assignment_Type, 0, &avp ) ); + value.i32=assignment_type; + CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); + } + + fd_msg_dump_walk(INFO,message); + CHECK_FCT( fd_msg_send( &message, NULL, NULL )); + + return 0; +} + +int test_sip_SAA_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, enum disp_action * act) +{ + + return 0; +} diff -r 44541db912a2 -r 3d9f300f3b49 extensions/test_sip/test_sip.c --- a/extensions/test_sip/test_sip.c Mon Jul 26 18:33:50 2010 +0900 +++ b/extensions/test_sip/test_sip.c Mon Jul 26 21:39:27 2010 +0900 @@ -129,6 +129,8 @@ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Host", &sip_dict.Destination_Host, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Realm", &sip_dict.Destination_Realm, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &sip_dict.Session_Id, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Redirect-Host", &sip_dict.Redirect_Host, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Redirect-Host-Usage", &sip_dict.Redirect_Host_Usage, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Auth-Data-Item", &sip_dict.SIP_Auth_Data_Item, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authorization", &sip_dict.SIP_Authorization, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authenticate", &sip_dict.SIP_Authenticate, ENOENT) ); @@ -136,11 +138,26 @@ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authentication-Scheme", &sip_dict.SIP_Authentication_Scheme, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authentication-Info", &sip_dict.SIP_Authentication_Info, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Server-URI", &sip_dict.SIP_Server_URI, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Server-Capabilities", &sip_dict.SIP_Server_Capabilities, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Mandatory-Capability", &sip_dict.SIP_Mandatory_Capability, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Optional-Capability", &sip_dict.SIP_Optional_Capability, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Method", &sip_dict.SIP_Method, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-AOR", &sip_dict.SIP_AOR, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Deregistration-Reason", &sip_dict.SIP_Deregistration_Reason, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Reason-Code", &sip_dict.SIP_Reason_Code, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Reason-Info", &sip_dict.SIP_Reason_Info, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Accounting-Information", &sip_dict.SIP_Accounting_Information, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Accounting-Server-URI", &sip_dict.SIP_Accounting_Server_URI, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Credit-Control-Server-URI", &sip_dict.SIP_Credit_Control_Server_URI, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Server-Assignment-Type", &sip_dict.SIP_Server_Assignment_Type, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Item-Number", &sip_dict.SIP_Item_Number, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Authorization-Type", &sip_dict.SIP_User_Authorization_Type, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Supported-User-Data-Type", &sip_dict.SIP_Supported_User_Data_Type, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Data", &sip_dict.SIP_User_Data, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Data-Type", &sip_dict.SIP_User_Data_Type, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Data-Contents", &sip_dict.SIP_User_Data_Contents, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Data-Already-Available", &sip_dict.SIP_User_Data_Already_Available, ENOENT) ); + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Visited-Network-Id", &sip_dict.SIP_Visited_Network_Id, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Realm", &sip_dict.Digest_Realm, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-URI", &sip_dict.Digest_URI, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Nonce", &sip_dict.Digest_Nonce, ENOENT) ); @@ -154,7 +171,6 @@ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Algorithm", &sip_dict.Digest_Algorithm, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-QoP", &sip_dict.Digest_QOP, ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "User-Name", &sip_dict.User_Name, ENOENT) ); - CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-HA1", &sip_dict.Digest_HA1, ENOENT) ); @@ -165,10 +181,14 @@ //**Command Codes /**/ - //MAR + //MAA CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Multimedia-Auth-Answer", &data.command, ENOENT) ); CHECK_FCT( fd_disp_register( test_sip_MAA_cb, DISP_HOW_CC, &data, &test_sip_MAA_hdl ) ); + //UAA + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "User-Authorization-Answer", &data.command, ENOENT) ); + CHECK_FCT( fd_disp_register( test_sip_UAA_cb, DISP_HOW_CC, &data, &test_sip_UAA_hdl ) ); + //RTR CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Registration-Termination-Request", &data.command, ENOENT) ); CHECK_FCT( fd_disp_register( test_sip_RTR_cb, DISP_HOW_CC, &data, &test_sip_RTR_hdl ) ); @@ -177,6 +197,9 @@ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Location-Info-Answer", &data.command, ENOENT) ); CHECK_FCT( fd_disp_register( test_sip_LIA_cb, DISP_HOW_CC, &data, &test_sip_LIA_hdl ) ); + //LIA + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Server-Assignment-Answer", &data.command, ENOENT) ); + CHECK_FCT( fd_disp_register( test_sip_SAA_cb, DISP_HOW_CC, &data, &test_sip_SAA_hdl ) ); //Callback for unexpected messages CHECK_FCT( fd_disp_register( test_sip_default_cb, DISP_HOW_APPID, &data, &test_sip_default_hdl ) ); @@ -188,7 +211,9 @@ */ CHECK_FCT(fd_sess_handler_create(&ts_sess_hdl, free)); - CHECK_FCT( fd_sig_register(30, "test_sip", (void *)test_sip_LIR_cb ) ); + //CHECK_FCT( fd_sig_register(30, "test_sip", (void *)test_sipSL_LIR_cb ) ); + CHECK_FCT( fd_sig_register(30, "test_sip", (void *)test_sip_SAR_cb ) ); + CHECK_FCT( fd_sig_register(31, "test_sip", (void *)test_sip_LIR_cb ) ); return 0; } diff -r 44541db912a2 -r 3d9f300f3b49 extensions/test_sip/test_sip.h --- a/extensions/test_sip/test_sip.h Mon Jul 26 18:33:50 2010 +0900 +++ b/extensions/test_sip/test_sip.h Mon Jul 26 21:39:27 2010 +0900 @@ -57,16 +57,32 @@ struct dict_object * Auth_Session_State; struct dict_object * Auth_Application_Id; struct dict_object * Destination_Host; - struct dict_object * Destination_Realm; struct dict_object * User_Name; struct dict_object * Session_Id; + struct dict_object * Redirect_Host; + struct dict_object * Redirect_Host_Usage; struct dict_object * SIP_Auth_Data_Item; + struct dict_object * SIP_Accounting_Information; + struct dict_object * SIP_Accounting_Server_URI; + struct dict_object * SIP_Credit_Control_Server_URI; + struct dict_object * SIP_Server_Assignment_Type; + struct dict_object * SIP_Item_Number; + struct dict_object * SIP_User_Authorization_Type; + struct dict_object * SIP_Supported_User_Data_Type; + struct dict_object * SIP_User_Data; + struct dict_object * SIP_User_Data_Type; + struct dict_object * SIP_User_Data_Contents; + struct dict_object * SIP_User_Data_Already_Available; + struct dict_object * SIP_Visited_Network_Id; struct dict_object * SIP_Authorization; struct dict_object * SIP_Authenticate; struct dict_object * SIP_Number_Auth_Items; struct dict_object * SIP_Authentication_Scheme; struct dict_object * SIP_Authentication_Info; struct dict_object * SIP_Server_URI; + struct dict_object * SIP_Server_Capabilities; + struct dict_object * SIP_Mandatory_Capability; + struct dict_object * SIP_Optional_Capability; struct dict_object * SIP_Method; struct dict_object * SIP_AOR; struct dict_object * SIP_Deregistration_Reason; @@ -84,6 +100,7 @@ struct dict_object * Digest_QOP; struct dict_object * Digest_Algorithm; struct dict_object * Digest_HA1; + struct dict_object * Destination_Realm; }; extern struct sip_dict sip_dict; @@ -93,9 +110,14 @@ void fd_ext_fini(void); int test_sip_LIR_cb(); +int test_sip_UAR_cb(); +int test_sip_SAR_cb(); +int test_sipSL_LIR_cb(); int test_sip_default_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act); int test_sip_MAA_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act); int test_sip_RTR_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act); +int test_sip_UAA_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act); int test_sip_LIA_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act); - +int test_sip_SAA_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act); +int test_sipSL_LIA_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act); diff -r 44541db912a2 -r 3d9f300f3b49 extensions/test_sip/userauthorization.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extensions/test_sip/userauthorization.c Mon Jul 26 21:39:27 2010 +0900 @@ -0,0 +1,165 @@ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Alexandre Westfahl * +* * +* 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 "test_sip.h" + +//Called to send a UAR +int test_sip_UAR_cb() +{ + struct dict_object * uar_model=NULL; + struct msg * message=NULL; + struct avp *avp=NULL; + struct session *sess=NULL; + union avp_value value; + + //Fake values START + unsigned char *sip_aor="sip:aw-lappy@tera.ics.keio.ac.jp"; + size_t aor_len=strlen(sip_aor); + unsigned char *destination_realm="tera.ics.keio.ac.jp"; + size_t destination_realmlen=strlen(destination_realm); + unsigned char *destination_host="suika.tera.ics.keio.ac.jp"; + size_t destination_hostlen=strlen(destination_host); + unsigned char *username="aw-lappy"; + size_t usernamelen=strlen(username); + unsigned char *visitednetwork="Pink"; + size_t visitednetworklen=strlen(visitednetwork); + int registrationtype = 2; + //Fake values STOP + + //Create the base message for an RTR + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "User-Authorization-Request", &uar_model, ENOENT) ); + CHECK_FCT( fd_msg_new (uar_model, 0, &message)); + + + + // Create a new session + { + CHECK_FCT( fd_sess_new( &sess, fd_g_config->cnf_diamid, "appsip", 6 )); + char * sid; + CHECK_FCT( fd_sess_getsid ( sess, &sid )); + CHECK_FCT( fd_msg_avp_new ( sip_dict.Session_Id, 0, &avp )); + value.os.data = (uint8_t *)sid; + value.os.len = strlen(sid); + CHECK_FCT( fd_msg_avp_setvalue( avp, &value )); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp )); + } + + //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 ( message, MSG_BRW_LAST_CHILD, avp) ); + } + + //Auth_Session_State + { + CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) ); + value.i32=1; + CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); + } + + //Origin_Host & Origin_Realm + CHECK_FCT( fd_msg_add_origin ( message, 0 )); + + //Destination_Host + { + CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Host, 0, &avp ) ); + value.os.data=destination_host; + value.os.len=destination_hostlen; + CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); + } + //Destination_Realm + { + CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Realm, 0, &avp ) ); + value.os.data=destination_realm; + value.os.len=destination_realmlen; + CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); + } + + //SIP_AOR + { + + CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) ); + value.os.data=sip_aor; + value.os.len=aor_len; + CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); + + } + //Username + { + + CHECK_FCT( fd_msg_avp_new ( sip_dict.User_Name, 0, &avp ) ); + value.os.data=username; + value.os.len=usernamelen; + CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); + + } + //Visited Network + { + + CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Visited_Network_Id, 0, &avp ) ); + value.os.data=visitednetwork; + value.os.len=visitednetworklen; + CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); + + } + //Authorization Type + { + + CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_User_Authorization_Type, 0, &avp ) ); + value.i32=registrationtype; + CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) ); + CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) ); + + } + + fd_msg_dump_walk(INFO,message); + CHECK_FCT( fd_msg_send( &message, NULL, NULL )); + + return 0; +} + +int test_sip_UAA_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, enum disp_action * act) +{ + + return 0; +}