blob: 6442ff47d2e7b0419b657b34a39dfa8ce07c135f [file] [log] [blame]
/*********************************************************************************************************
* Software License Agreement (BSD License) *
* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
* *
* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (Keio University), and the WIDE Project. *
* *
* All rights reserved. *
* *
* Redistribution and use of this software in source and binary forms, with or without modification, are *
* permitted provided that the following conditions are met: *
* *
* * Redistributions of source code must retain the above *
* copyright notice, this list of conditions and the *
* following disclaimer. *
* *
* * Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the *
* following disclaimer in the documentation and/or other *
* materials provided with the distribution. *
* *
* * Neither the name of the Teraoka Laboratory nor the *
* names of its contributors may be used to endorse or *
* promote products derived from this software without *
* specific prior written permission of Teraoka Laboratory *
* *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
*********************************************************************************************************/
//#include <mysql.h>
#include "app_sip.h"
MYSQL *conn;
void clear_digest(uint8_t * digest, char * readable_digest, int digestlength)
{
int i=0;
for(i=0;i<digestlength * 2;i++)
sprintf(&readable_digest[2 * i], "%2.2hhx", digest[i]);
readable_digest[2 * digestlength]='\0';
return;
}
// You must create a table like this "char clearDigest[DIGEST_LEN*2+1];"
void calc_md5(char *clearDigest, char * data)
{
gcry_md_hd_t md5;
uint8_t * binDigest=NULL;
CHECK_MALLOC_DO(binDigest=malloc(DIGEST_LEN),return);
gcry_md_open(&md5,GCRY_MD_MD5, 0);
gcry_md_write(md5, (char *)data, sizeof(data));
memcpy(binDigest, gcry_md_read(md5, GCRY_MD_MD5),gcry_md_get_algo_dlen(GCRY_MD_MD5));
gcry_md_close(md5);
clear_digest(binDigest, clearDigest, DIGEST_LEN);
free(binDigest);
return;
}
/* Search a given AVP model in an AVP (extracted from libfreediameter/message.c ) */
int fd_avp_search_avp ( struct avp * groupedavp, struct dict_object * what, struct avp ** avp )
{
struct avp * nextavp;
struct avp_hdr * nextavphdr;
struct dict_avp_data dictdata;
TRACE_ENTRY("%p %p %p", groupedavp, what, avp);
CHECK_FCT( fd_dict_getval(what, &dictdata) );
// Loop only in the group AVP
CHECK_FCT( fd_msg_browse(groupedavp, MSG_BRW_FIRST_CHILD, (void *)&nextavp, NULL) );
CHECK_FCT( fd_msg_avp_hdr( nextavp, &nextavphdr ) );
while (nextavphdr) {
if ( (nextavphdr->avp_code == dictdata.avp_code) && (nextavphdr->avp_vendor == dictdata.avp_vendor) ) // always 0 if no Vendor flag
{
break;
}
// Otherwise move to next AVP in the grouped AVP
CHECK_FCT( fd_msg_browse(nextavp, MSG_BRW_NEXT, (void *)&nextavp, NULL) );
if(nextavp!=NULL)
{
CHECK_FCT( fd_msg_avp_hdr( nextavp, &nextavphdr ) );
}
else
nextavphdr=NULL;
}
if (avp)
*avp = nextavp;
if (avp && nextavp) {
struct dictionary * dict;
CHECK_FCT( fd_dict_getdict( what, &dict) );
CHECK_FCT_DO( fd_msg_parse_dict( nextavp, dict, NULL ), );
}
if (avp || nextavp)
return 0;
else
return ENOENT;
}
struct avp_hdr *walk_digest(struct avp *avp, int avp_code)
{
struct avp_hdr *temphdr=NULL;
CHECK_FCT_DO(fd_msg_browse ( avp, MSG_BRW_WALK, &avp, NULL),return NULL);
while(avp!=NULL)
{
CHECK_FCT_DO( fd_msg_avp_hdr( avp,&temphdr ),return NULL);
if(temphdr->avp_code==avp_code)
{
//We found the AVP so we set avp to NULL to exit the loop
avp=NULL;
return temphdr;
}
else if(temphdr->avp_code==380)//SIP-Authorization AVP
{
//We didn't found the AVP but we finished browsing the Authentication AVP
avp=NULL;
temphdr=NULL;
return temphdr;
}
else
{
CHECK_FCT_DO(fd_msg_browse ( avp, MSG_BRW_WALK, &avp, NULL),return NULL);
temphdr=NULL;
}
}
return temphdr;
}
int start_mysql_connection()
{
conn = mysql_init(NULL);
mysql_options(conn, MYSQL_OPT_RECONNECT, "true");
if (!mysql_real_connect(conn, as_conf->mysql_server,as_conf->mysql_login, as_conf->mysql_password, as_conf->mysql_database, as_conf->mysql_port, NULL, 0))
{//TODO: display error from mysql
TRACE_DEBUG(INFO,"Unable to connect to database (%s) with login:%s",as_conf->mysql_database,as_conf->mysql_login);
return 1;
}
return 0;
}
void request_mysql(char *query)
{
//We check if the connection is still up
mysql_ping(conn);
if (mysql_query(conn, query))
{
TRACE_DEBUG(INFO,"Query %s failed", query);
}
}
void close_mysql_connection()
{
mysql_close(conn);
}
//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=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;
//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;
}
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:
//We must never go here, if so, we must stop diameter_sip
diameter_uri=NULL;
return 2;
break;
}
//0 if it was found
return not_found;
}
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 add_user_datatype(const unsigned char *sip_aor, const size_t sipaorlen,struct msg *message)
{
CHECK_PARAMS(sip_aor && sipaorlen && message );
size_t querylen, sipaorpurelen;
char *query, *sipaor_pure;
int not_found=2;
union avp_value value;
struct avp *avp, *rootavp;
unsigned long *length;
//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_GETSIPDATA_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_GETSIPDATA, 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)
{
length=mysql_fetch_lengths(res);
if(strlen(row[0])>1)
{
CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_User_Data, 0, &rootavp ) );
CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_User_Data_Type, 0, &avp ) );
CHECK_MALLOC(value.os.data=malloc(length[0]*sizeof(unsigned char)));
strncpy((char *)value.os.data,(char *)row[0],length[0]);
value.os.len=(size_t)length[0];
CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
CHECK_FCT( fd_msg_avp_add ( rootavp, MSG_BRW_LAST_CHILD, avp) );
CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_User_Data_Contents, 0, &avp ) );
CHECK_MALLOC(value.os.data=malloc(length[1]*sizeof(unsigned char)));
memcpy(value.os.data,row[1],length[1]);
value.os.len=(size_t)length[1];
CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
CHECK_FCT( fd_msg_avp_add ( rootavp, MSG_BRW_LAST_CHILD, avp) );
//We add SIP_User_Data to message
CHECK_FCT( fd_msg_avp_add ( message, MSG_BRW_LAST_CHILD, rootavp) );
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;
}
int set_pending_flag(const unsigned char *username, const size_t usernamelen)
{
CHECK_PARAMS(username && usernamelen);
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_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);
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);
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);
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);
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, unsigned 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((char *)*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_avp(struct msg * message, int code, int vendor)
{
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==code && temphdr->avp_vendor==vendor)
{
counter++;
}
CHECK_FCT(fd_msg_browse (avp, MSG_BRW_WALK, &avp, NULL));
}
return counter;
}
/*
void nonce_add_element(char * nonce)
{
noncechain *newelt=malloc(sizeof(noncechain));
newelt->nonce=nonce;
newelt->timestamp=(int)time(NULL);
newelt->next=NULL;
if(listnonce==NULL)
{
listnonce=newelt;
}
else
{
noncechain* temp=listnonce;
while(temp->next != NULL)
{
if(temp->timestamp < ((int)time(NULL)-300))
{
listnonce=temp->next;
free(temp);
temp=listnonce;
}
temp = temp->next;
}
temp->next = newelt;
}
}
void nonce_del_element(char * nonce)
{
if(listnonce!=NULL)
{
noncechain *temp=listnonce, *tempbefore=NULL;
if(listnonce->next==NULL && strcmp(listnonce->nonce,nonce)==0)
{
free(listnonce);
listnonce=NULL;
return;
}
while(temp->next != NULL)
{
if(strcmp(temp->nonce,nonce)==0)
{
if(tempbefore==NULL)
{
listnonce=temp->next;
free(temp);
return;
}
tempbefore->next=temp->next;
free(temp);
break;
}
tempbefore=temp;
temp = temp->next;
}
}
}
int nonce_check_element(char * nonce)
{
if(listnonce==NULL)
{
//Not found
return 0;
}
else
{
noncechain* temp=listnonce;
while(temp->next != NULL)
{
if(strcmp(temp->nonce,nonce)==0)
return 1;
else
temp = temp->next;
}
}
return 0;
}
void nonce_deletelistnonce()
{
if(listnonce !=NULL)
{
noncechain* temp=listnonce;
while(listnonce->next != NULL)
{
temp = listnonce->next;
free(listnonce);
listnonce=temp;
}
free(listnonce);
}
}
*/