blob: 6442ff47d2e7b0419b657b34a39dfa8ce07c135f [file] [log] [blame]
Brian Waters13d96012017-12-08 16:53:31 -06001/*********************************************************************************************************
2* Software License Agreement (BSD License) *
3* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
4* *
5* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (Keio University), and the WIDE Project. *
6* *
7* All rights reserved. *
8* *
9* Redistribution and use of this software in source and binary forms, with or without modification, are *
10* permitted provided that the following conditions are met: *
11* *
12* * Redistributions of source code must retain the above *
13* copyright notice, this list of conditions and the *
14* following disclaimer. *
15* *
16* * Redistributions in binary form must reproduce the above *
17* copyright notice, this list of conditions and the *
18* following disclaimer in the documentation and/or other *
19* materials provided with the distribution. *
20* *
21* * Neither the name of the Teraoka Laboratory nor the *
22* names of its contributors may be used to endorse or *
23* promote products derived from this software without *
24* specific prior written permission of Teraoka Laboratory *
25* *
26* *
27* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
28* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
29* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
30* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
31* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
32* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
33* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
34* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
35*********************************************************************************************************/
36//#include <mysql.h>
37#include "app_sip.h"
38
39MYSQL *conn;
40
41void clear_digest(uint8_t * digest, char * readable_digest, int digestlength)
42{
43 int i=0;
44 for(i=0;i<digestlength * 2;i++)
45 sprintf(&readable_digest[2 * i], "%2.2hhx", digest[i]);
46 readable_digest[2 * digestlength]='\0';
47
48 return;
49}
50
51// You must create a table like this "char clearDigest[DIGEST_LEN*2+1];"
52void calc_md5(char *clearDigest, char * data)
53{
54 gcry_md_hd_t md5;
55 uint8_t * binDigest=NULL;
56
57 CHECK_MALLOC_DO(binDigest=malloc(DIGEST_LEN),return);
58
59 gcry_md_open(&md5,GCRY_MD_MD5, 0);
60 gcry_md_write(md5, (char *)data, sizeof(data));
61 memcpy(binDigest, gcry_md_read(md5, GCRY_MD_MD5),gcry_md_get_algo_dlen(GCRY_MD_MD5));
62 gcry_md_close(md5);
63
64 clear_digest(binDigest, clearDigest, DIGEST_LEN);
65 free(binDigest);
66 return;
67}
68
69
70/* Search a given AVP model in an AVP (extracted from libfreediameter/message.c ) */
71int fd_avp_search_avp ( struct avp * groupedavp, struct dict_object * what, struct avp ** avp )
72{
73 struct avp * nextavp;
74 struct avp_hdr * nextavphdr;
75 struct dict_avp_data dictdata;
76
77
78 TRACE_ENTRY("%p %p %p", groupedavp, what, avp);
79
80 CHECK_FCT( fd_dict_getval(what, &dictdata) );
81
82 // Loop only in the group AVP
83 CHECK_FCT( fd_msg_browse(groupedavp, MSG_BRW_FIRST_CHILD, (void *)&nextavp, NULL) );
84 CHECK_FCT( fd_msg_avp_hdr( nextavp, &nextavphdr ) );
85
86 while (nextavphdr) {
87
88 if ( (nextavphdr->avp_code == dictdata.avp_code) && (nextavphdr->avp_vendor == dictdata.avp_vendor) ) // always 0 if no Vendor flag
89 {
90 break;
91 }
92
93 // Otherwise move to next AVP in the grouped AVP
94 CHECK_FCT( fd_msg_browse(nextavp, MSG_BRW_NEXT, (void *)&nextavp, NULL) );
95
96 if(nextavp!=NULL)
97 {
98 CHECK_FCT( fd_msg_avp_hdr( nextavp, &nextavphdr ) );
99 }
100 else
101 nextavphdr=NULL;
102 }
103 if (avp)
104 *avp = nextavp;
105
106 if (avp && nextavp) {
107 struct dictionary * dict;
108 CHECK_FCT( fd_dict_getdict( what, &dict) );
109 CHECK_FCT_DO( fd_msg_parse_dict( nextavp, dict, NULL ), );
110 }
111
112 if (avp || nextavp)
113 return 0;
114 else
115 return ENOENT;
116}
117struct avp_hdr *walk_digest(struct avp *avp, int avp_code)
118{
119 struct avp_hdr *temphdr=NULL;
120 CHECK_FCT_DO(fd_msg_browse ( avp, MSG_BRW_WALK, &avp, NULL),return NULL);
121
122 while(avp!=NULL)
123 {
124
125 CHECK_FCT_DO( fd_msg_avp_hdr( avp,&temphdr ),return NULL);
126
127 if(temphdr->avp_code==avp_code)
128 {
129 //We found the AVP so we set avp to NULL to exit the loop
130 avp=NULL;
131 return temphdr;
132
133 }
134 else if(temphdr->avp_code==380)//SIP-Authorization AVP
135 {
136 //We didn't found the AVP but we finished browsing the Authentication AVP
137 avp=NULL;
138 temphdr=NULL;
139
140 return temphdr;
141 }
142 else
143 {
144 CHECK_FCT_DO(fd_msg_browse ( avp, MSG_BRW_WALK, &avp, NULL),return NULL);
145 temphdr=NULL;
146
147 }
148 }
149
150 return temphdr;
151}
152
153int start_mysql_connection()
154{
155 conn = mysql_init(NULL);
156
157 mysql_options(conn, MYSQL_OPT_RECONNECT, "true");
158
159 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))
160 {//TODO: display error from mysql
161 TRACE_DEBUG(INFO,"Unable to connect to database (%s) with login:%s",as_conf->mysql_database,as_conf->mysql_login);
162 return 1;
163 }
164 return 0;
165
166}
167
168
169void request_mysql(char *query)
170{
171 //We check if the connection is still up
172 mysql_ping(conn);
173
174 if (mysql_query(conn, query))
175 {
176 TRACE_DEBUG(INFO,"Query %s failed", query);
177
178 }
179
180}
181
182void close_mysql_connection()
183{
184 mysql_close(conn);
185
186}
187
188//If password is null, we just verify this user exist
189//We don't need the password length because it is a table'
190int get_password(const unsigned char *username, const size_t usernamelen, char *password)
191{
192 CHECK_PARAMS(username && usernamelen);
193
194 int not_found=2;
195 size_t querylen, usernamepurelen;
196 char *query, *username_pure;
197
198 switch(as_conf->datasource)
199 {
200 //MySQL
201 case ASMYSQL:
202 //We allocate the double size of username because at worst it can be all quotes
203 username_pure=malloc(usernamelen*2+1);
204 //We purify username not to have forbidden characters
205 usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen);
206
207 //We copy username in query
208 querylen=SQL_GETPASSWORD_LEN + usernamepurelen;
209 query = malloc(querylen+2);
210 snprintf(query, querylen+1, SQL_GETPASSWORD, username_pure);
211
212 MYSQL_RES *res;
213 MYSQL_ROW row;
214
215 //We make the query
216 request_mysql(query);
217 res=mysql_use_result(conn);
218 if(res==NULL)
219 {
220 if(password!=NULL)
221 password[0]='\0';
222 free(query);
223 return 2;
224 }
225
226
227
228 while ((row = mysql_fetch_row(res)) != NULL)
229 {
230 if(strlen(row[0])>0)
231 {
232 if(password!=NULL)
233 strcpy(password,row[0]);
234
235 not_found=0;
236 break;
237 }
238 }
239 mysql_free_result(res);
240 free(query);
241 break;
242 }
243 return not_found;
244}
245
246int check_sipaor(const unsigned char *username, const size_t usernamelen, const char * sip_aor,const size_t sipaorlen)
247{
248 CHECK_PARAMS(username && usernamelen && sip_aor && sipaorlen);
249
250 int not_found=2;
251 size_t querylen, usernamepurelen;
252 char *query, *username_pure;
253
254 switch(as_conf->datasource)
255 {
256 //MySQL
257 case ASMYSQL:
258 //We allocate the double size of username because at worst it can be all quotes
259 username_pure=malloc(usernamelen*2+1);
260 //We purify username not to have forbidden characters
261 usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen);
262
263 //We get the list of AOR owned by this user
264 querylen=SQL_GETSIPAOR_LEN + usernamepurelen;
265 query = malloc(querylen+2);
266 snprintf(query, querylen+1, SQL_GETSIPAOR, username_pure);
267
268 MYSQL_RES *res;
269 MYSQL_ROW row;
270
271 //We make the query
272 request_mysql(query);
273 res=mysql_use_result(conn);
274 if(res==NULL)
275 {
276 free(query);
277 return 2;
278 }
279
280
281 not_found=1;
282 while ((row = mysql_fetch_row(res)) != NULL)
283 {
284 if(strncmp((const char *)sip_aor,row[0],sipaorlen)==0)
285 {
286 not_found=0;
287 break;
288 }
289 }
290 mysql_free_result(res);
291 free(query);
292 break;
293 }
294 return not_found;
295}
296
297int get_diameter_uri(const unsigned char *sip_aor, const size_t sipaorlen, char ** diameter_uri, size_t *diameterurilen)
298{
299 CHECK_PARAMS(sip_aor && sipaorlen);
300
301 size_t querylen, sipaorpurelen;
302 char *query, *sipaor_pure;
303 int not_found=2;
304
305
306
307
308 //a sip aor must begin by "sip:" or "sips:" so it must at least be longer than 4 chars
309 if(sipaorlen<5)
310 return 2;
311
312 //NOTE: each method has to purify sip_aor itself. You must remove quotes or special chars for security
313 switch(as_conf->datasource)
314 {
315 //MySQL
316 case ASMYSQL:
317
318 querylen=SQL_GETDIAMURI_LEN + sipaorlen;
319
320
321 //We allocate the double size of SIP-URI because at worst it can be all quotes
322 CHECK_MALLOC(sipaor_pure=malloc(sipaorlen*2+1));
323 //We purify SIP-URI not to have forbidden characters
324 sipaorpurelen=mysql_real_escape_string(conn, sipaor_pure, (const char *)sip_aor, sipaorlen);
325
326
327 query = malloc(querylen+sipaorpurelen+ 2);
328 snprintf(query, querylen+1, SQL_GETDIAMURI, sipaor_pure);
329
330 MYSQL_RES *res;
331 MYSQL_ROW row;
332
333
334 //We make the query
335 request_mysql(query);
336 res=mysql_use_result(conn);
337 if(res==NULL)
338 {
339 //We couldn't make the request
340 diameter_uri=NULL;
341 return 2;
342 }
343
344 while ((row = mysql_fetch_row(res)) != NULL)
345 {
346 *diameterurilen=strlen(row[0]);
347 if(*diameterurilen>0)
348 {
349 CHECK_MALLOC(*diameter_uri=malloc(*diameterurilen+1));
350 strcpy(*diameter_uri,row[0]);
351 not_found=0;
352 break;
353 }
354 }
355 mysql_free_result(res);
356 free(query);
357 free(sipaor_pure);
358 break;
359
360 default:
361
362 //We must never go here, if so, we must stop diameter_sip
363 diameter_uri=NULL;
364 return 2;
365
366 break;
367 }
368
369 //0 if it was found
370 return not_found;
371
372}
373
374
375int exist_username(const unsigned char *sip_aor, const size_t sipaorlen)
376{
377 CHECK_PARAMS(sip_aor && sipaorlen);
378
379 size_t querylen, sipaorpurelen;
380 char *query, *sipaor_pure;
381 int not_found=1;
382
383 //a sip aor must begin by "sip:" or "sips:" so it must at least be longer than 4 chars
384 if(sipaorlen<5)
385 return 2;
386
387 //NOTE: each method has to purify sip_aor itself. You must remove quotes or special chars for security
388
389 switch(as_conf->datasource)
390 {
391 //MySQL
392 case ASMYSQL:
393
394 querylen=SQL_GETUSERNAME_LEN + sipaorlen;
395
396
397 //We allocate the double size of SIP-URI because at worst it can be all quotes
398 CHECK_MALLOC(sipaor_pure=malloc(sipaorlen*2+1));
399 //We purify SIP-URI not to have forbidden characters
400 sipaorpurelen=mysql_real_escape_string(conn, sipaor_pure, (const char *)sip_aor, sipaorlen);
401
402
403 query = malloc(querylen+sipaorpurelen+ 2);
404 snprintf(query, querylen+1, SQL_GETUSERNAME, sipaor_pure);
405
406 MYSQL_RES *res;
407 MYSQL_ROW row;
408
409
410 //We make the query
411 request_mysql(query);
412 res=mysql_use_result(conn);
413 if(res==NULL)
414 {
415 //We couldn't make the request
416 return 2;
417 }
418
419 while ((row = mysql_fetch_row(res)) != NULL)
420 {
421 if(strlen(row[0])>0)
422 {
423 not_found=0;
424 break;
425 }
426 }
427 mysql_free_result(res);
428 free(query);
429 free(sipaor_pure);
430 break;
431
432 default:
433
434 //We must never go here, if so, we must stop diameter_sip
435 TRACE_DEBUG(INFO,"FATAL ERROR: the datasource is unknown, please check your config file!");
436 return 2;
437
438 break;
439 }
440
441 //0 if it was found
442 return not_found;
443
444}
445
446//We check if this user can go in the given network
447int allow_roaming(const unsigned char *username, const size_t usernamelen, const char * network,const size_t networklen)
448{
449 CHECK_PARAMS(username && usernamelen && network && networklen);
450
451 int not_found=2;
452 size_t querylen, usernamepurelen;
453 char *query, *username_pure;
454
455 switch(as_conf->datasource)
456 {
457 //MySQL
458 case ASMYSQL:
459 //We allocate the double size of username because at worst it can be all quotes
460 username_pure=malloc(usernamelen*2+1);
461 //We purify username not to have forbidden characters
462 usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen);
463
464 //We get the list of AOR owned by this user
465 querylen=SQL_GETUSERNET_LEN + usernamepurelen;
466 query = malloc(querylen+2);
467 snprintf(query, querylen+1, SQL_GETUSERNET, username_pure);
468
469
470 MYSQL_RES *res;
471 MYSQL_ROW row;
472
473
474 //We make the query
475 request_mysql(query);
476 res=mysql_use_result(conn);
477 if(res==NULL)
478 {
479 free(query);
480 return 2;
481 }
482
483
484 not_found=1;
485 while ((row = mysql_fetch_row(res)) != NULL)
486 {
487 if(strncmp((const char *)network,row[0],networklen)==0)
488 {
489 not_found=0;
490 break;
491 }
492 }
493 mysql_free_result(res);
494 free(query);
495 break;
496 }
497 return not_found;
498}
499
500//SIP-Server-Capabilities for the SIP-AOR
501int get_sipserver_cap(const unsigned char *sip_aor, const size_t sipaorlen, struct avp **capabilities)
502{
503 CHECK_PARAMS(sip_aor && sipaorlen && capabilities);
504
505 size_t querylen, sipaorpurelen;
506 char *query, *sipaor_pure;
507 int not_found=2;
508 union avp_value value;
509 struct avp *avp;
510
511 //a sip aor must begin by "sip:" or "sips:" so it must at least be longer than 4 chars
512 if(sipaorlen<5)
513 return 2;
514
515 //NOTE: each method has to purify sip_aor itself. You must remove quotes or special chars for security
516 switch(as_conf->datasource)
517 {
518 //MySQL
519 case ASMYSQL:
520
521 querylen=SQL_GETSIPSERCAP_LEN + sipaorlen;
522
523
524 //We allocate the double size of SIP-URI because at worst it can be all quotes
525 CHECK_MALLOC(sipaor_pure=malloc(sipaorlen*2+1));
526 //We purify SIP-URI not to have forbidden characters
527 sipaorpurelen=mysql_real_escape_string(conn, sipaor_pure, (const char *)sip_aor, sipaorlen);
528
529
530 query = malloc(querylen+sipaorpurelen+ 2);
531 snprintf(query, querylen+1, SQL_GETSIPSERCAP, sipaor_pure);
532
533 MYSQL_RES *res;
534 MYSQL_ROW row;
535
536 //We make the query
537 request_mysql(query);
538 res=mysql_use_result(conn);
539 if(res==NULL)
540 {
541 //We couldn't make the request
542 return 2;
543 }
544 not_found=1;
545 while ((row = mysql_fetch_row(res)) != NULL)
546 {
547 if(atoi(row[0])==1)
548 {//mandatory
549 CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Mandatory_Capability, 0, &avp ) );
550 value.i32=(uint32_t)atoi(row[1]);
551 CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
552 CHECK_FCT( fd_msg_avp_add ( *capabilities, MSG_BRW_LAST_CHILD, avp) );
553
554 }
555 else
556 {//optional
557 CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Optional_Capability, 0, &avp ) );
558 value.i32=(uint32_t)atoi(row[1]);
559 CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
560 CHECK_FCT( fd_msg_avp_add ( *capabilities, MSG_BRW_LAST_CHILD, avp) );
561 }
562 not_found=0;
563 }
564
565 mysql_free_result(res);
566 free(query);
567 free(sipaor_pure);
568 break;
569
570 default:
571
572 //We must never go here, if so, we must stop diameter_sip
573 TRACE_DEBUG(INFO,"FATAL ERROR: the datasource is unknown, please check your config file!");
574 return 2;
575
576 break;
577 }
578
579 //0 if it was found
580 return not_found;
581
582}
583
584
585//We retrieve datatype
586int add_user_datatype(const unsigned char *sip_aor, const size_t sipaorlen,struct msg *message)
587{
588 CHECK_PARAMS(sip_aor && sipaorlen && message );
589
590 size_t querylen, sipaorpurelen;
591 char *query, *sipaor_pure;
592 int not_found=2;
593 union avp_value value;
594 struct avp *avp, *rootavp;
595 unsigned long *length;
596
597 //a sip aor must begin by "sip:" or "sips:" so it must at least be longer than 4 chars
598 if(sipaorlen<5)
599 return 2;
600
601 //NOTE: each method has to purify sip_aor itself. You must remove quotes or special chars for security
602 switch(as_conf->datasource)
603 {
604 //MySQL
605 case ASMYSQL:
606
607 querylen=SQL_GETSIPDATA_LEN + sipaorlen;
608
609
610 //We allocate the double size of SIP-URI because at worst it can be all quotes
611 CHECK_MALLOC(sipaor_pure=malloc(sipaorlen*2+1));
612 //We purify SIP-URI not to have forbidden characters
613 sipaorpurelen=mysql_real_escape_string(conn, sipaor_pure, (const char *)sip_aor, sipaorlen);
614
615
616 query = malloc(querylen+sipaorpurelen+ 2);
617 snprintf(query, querylen+1, SQL_GETSIPDATA, sipaor_pure);
618
619 MYSQL_RES *res;
620 MYSQL_ROW row;
621
622 //We make the query
623 request_mysql(query);
624 res=mysql_use_result(conn);
625 if(res==NULL)
626 {
627 //We couldn't make the request
628 return 2;
629 }
630 not_found=1;
631 while ((row = mysql_fetch_row(res)) != NULL)
632 {
633 length=mysql_fetch_lengths(res);
634
635 if(strlen(row[0])>1)
636 {
637 CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_User_Data, 0, &rootavp ) );
638
639 CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_User_Data_Type, 0, &avp ) );
640 CHECK_MALLOC(value.os.data=malloc(length[0]*sizeof(unsigned char)));
641 strncpy((char *)value.os.data,(char *)row[0],length[0]);
642 value.os.len=(size_t)length[0];
643 CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
644 CHECK_FCT( fd_msg_avp_add ( rootavp, MSG_BRW_LAST_CHILD, avp) );
645
646
647
648 CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_User_Data_Contents, 0, &avp ) );
649 CHECK_MALLOC(value.os.data=malloc(length[1]*sizeof(unsigned char)));
650 memcpy(value.os.data,row[1],length[1]);
651 value.os.len=(size_t)length[1];
652 CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
653 CHECK_FCT( fd_msg_avp_add ( rootavp, MSG_BRW_LAST_CHILD, avp) );
654
655 //We add SIP_User_Data to message
656 CHECK_FCT( fd_msg_avp_add ( message, MSG_BRW_LAST_CHILD, rootavp) );
657 not_found=0;
658 }
659
660 }
661
662 mysql_free_result(res);
663 free(query);
664 free(sipaor_pure);
665 break;
666
667 default:
668
669 //We must never go here, if so, we must stop diameter_sip
670 TRACE_DEBUG(INFO,"FATAL ERROR: the datasource is unknown, please check your config file!");
671 return 2;
672
673 break;
674 }
675
676 //0 if it was found
677 return not_found;
678
679
680
681}
682
683int set_pending_flag(const unsigned char *username, const size_t usernamelen)
684{
685 CHECK_PARAMS(username && usernamelen);
686
687
688 size_t querylen, usernamepurelen;
689 char *query, *username_pure;
690
691 switch(as_conf->datasource)
692 {
693 //MySQL
694 case ASMYSQL:
695 //We allocate the double size of username because at worst it can be all quotes
696 username_pure=malloc(usernamelen*2+1);
697 //We purify username not to have forbidden characters
698 usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen);
699
700
701
702 //We clear the flag "authentication pending"
703 querylen=SQL_SETFLAG_LEN + usernamepurelen;
704 query = malloc(querylen+2);
705 snprintf(query, querylen+1, SQL_SETFLAG, username_pure);
706
707 if (mysql_query(conn, query))
708 {
709 TRACE_DEBUG(INFO,"Query %s failed", query);
710 free(query);
711 return 2;
712 }
713
714 free(query);
715 break;
716 }
717 return 0;
718}
719int clear_pending_flag(const unsigned char *username, const size_t usernamelen)
720{
721 CHECK_PARAMS(username && usernamelen);
722
723
724 size_t querylen, usernamepurelen;
725 char *query, *username_pure;
726
727 switch(as_conf->datasource)
728 {
729 //MySQL
730 case ASMYSQL:
731 //We allocate the double size of username because at worst it can be all quotes
732 username_pure=malloc(usernamelen*2+1);
733 //We purify username not to have forbidden characters
734 usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen);
735
736
737
738 //We clear the flag "authentication pending"
739 querylen=SQL_CLEARFLAG_LEN + usernamepurelen;
740 query = malloc(querylen+2);
741 snprintf(query, querylen+1, SQL_CLEARFLAG, username_pure);
742
743 if (mysql_query(conn, query))
744 {
745 TRACE_DEBUG(INFO,"Query %s failed", query);
746 free(query);
747 return 2;
748 }
749
750 free(query);
751 break;
752 }
753 return 0;
754}
755
756
757
758int set_sipserver_uri(const unsigned char *username, const size_t usernamelen, const unsigned char *sipserver_uri,const size_t sipserverurilen)
759{
760 CHECK_PARAMS(username && usernamelen && sipserver_uri && sipserverurilen);
761
762
763 size_t querylen, usernamepurelen, sipserveruripurelen;
764 char *query, *username_pure, *sipserveruri_pure;
765
766 switch(as_conf->datasource)
767 {
768 //MySQL
769 case ASMYSQL:
770 //We allocate the double size of username because at worst it can be all quotes
771 username_pure=malloc(usernamelen*2+1);
772 //We purify username not to have forbidden characters
773 usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen);
774
775 //We allocate the double size of username because at worst it can be all quotes
776 sipserveruri_pure=malloc(sipserverurilen*2+1);
777 //We purify username not to have forbidden characters
778 sipserveruripurelen=mysql_real_escape_string(conn, sipserveruri_pure, (const char *)sipserver_uri, sipserverurilen);
779
780 //We clear the flag "authentication pending"
781 querylen=SQL_SETSIPURI_LEN + usernamepurelen + sipserveruripurelen;
782 query = malloc(querylen+2);
783 snprintf(query, querylen+1, SQL_SETSIPURI, sipserveruri_pure,username_pure);
784
785 if (mysql_query(conn, query))
786 {
787 TRACE_DEBUG(INFO,"Query %s failed", query);
788 free(query);
789 return 2;
790 }
791
792 free(query);
793 break;
794 }
795 return 0;
796}
797int remove_sipserver_uri(const unsigned char *sipserver_uri,const size_t sipserverurilen)
798{
799 CHECK_PARAMS(sipserver_uri && sipserverurilen);
800
801
802 size_t querylen, sipserveruripurelen;
803 char *query, *sipserveruri_pure;
804
805 switch(as_conf->datasource)
806 {
807 //MySQL
808 case ASMYSQL:
809 //We allocate the double size of username because at worst it can be all quotes
810 sipserveruri_pure=malloc(sipserverurilen*2+1);
811 //We purify username not to have forbidden characters
812 sipserveruripurelen=mysql_real_escape_string(conn, sipserveruri_pure, (const char *)sipserver_uri, sipserverurilen);
813
814 //We clear the flag "authentication pending"
815 querylen=SQL_RMSIPURI_LEN + sipserveruripurelen;
816 query = malloc(querylen+2);
817 snprintf(query, querylen+1, SQL_RMSIPURI, sipserveruri_pure);
818
819 if (mysql_query(conn, query))
820 {
821 TRACE_DEBUG(INFO,"Query %s failed", query);
822 free(query);
823 return 2;
824 }
825
826 free(query);
827 break;
828 }
829 return 0;
830}
831int set_real_sipserver_uri(const unsigned char *username, const size_t usernamelen, const unsigned char *sipserver_uri,const size_t sipserverurilen)
832{
833 CHECK_PARAMS(username && usernamelen && sipserver_uri && sipserverurilen);
834
835
836 size_t querylen, usernamepurelen, sipserveruripurelen;
837 char *query, *username_pure, *sipserveruri_pure;
838
839 switch(as_conf->datasource)
840 {
841 //MySQL
842 case ASMYSQL:
843 //We allocate the double size of username because at worst it can be all quotes
844 username_pure=malloc(usernamelen*2+1);
845 //We purify username not to have forbidden characters
846 usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen);
847
848 //We allocate the double size of username because at worst it can be all quotes
849 sipserveruri_pure=malloc(sipserverurilen*2+1);
850 //We purify username not to have forbidden characters
851 sipserveruripurelen=mysql_real_escape_string(conn, sipserveruri_pure, (const char *)sipserver_uri, sipserverurilen);
852
853 //We clear the flag "authentication pending"
854 querylen=SQL_SETREALSIPURI_LEN + usernamepurelen + sipserveruripurelen;
855 query = malloc(querylen+2);
856 snprintf(query, querylen+1, SQL_SETREALSIPURI, sipserveruri_pure,username_pure);
857
858 if (mysql_query(conn, query))
859 {
860 TRACE_DEBUG(INFO,"Query %s failed", query);
861 free(query);
862 return 2;
863 }
864
865 free(query);
866 break;
867 }
868 return 0;
869}
870
871int get_sipserver_uri(const unsigned char *sip_aor, const size_t sipaorlen, unsigned char ** sipserver_uri, size_t *sipserverurilen)
872{
873 CHECK_PARAMS(sip_aor && sipaorlen && sipserver_uri && sipserverurilen );
874
875 size_t querylen, sipaorpurelen;
876 char *query, *sipaor_pure;
877 int not_found=2;
878
879
880
881
882 //a sip aor must begin by "sip:" or "sips:" so it must at least be longer than 4 chars
883 if(sipaorlen<5)
884 return 2;
885
886 //NOTE: each method has to purify sip_aor itself. You must remove quotes or special chars for security
887
888 switch(as_conf->datasource)
889 {
890 //MySQL
891 case ASMYSQL:
892
893 querylen=SQL_GETSIPSERURI_LEN + sipaorlen;
894
895 //We allocate the double size of SIP-URI because at worst it can be all quotes
896 CHECK_MALLOC(sipaor_pure=malloc(sipaorlen*2+1));
897 //We purify SIP-URI not to have forbidden characters
898 sipaorpurelen=mysql_real_escape_string(conn, sipaor_pure, (const char *)sip_aor, sipaorlen);
899
900
901 query = malloc(querylen+sipaorpurelen+ 2);
902 snprintf(query, querylen+1, SQL_GETSIPSERURI, sipaor_pure);
903
904 MYSQL_RES *res;
905 MYSQL_ROW row;
906
907 //We make the query
908 request_mysql(query);
909 res=mysql_use_result(conn);
910 if(res==NULL)
911 {
912 //We couldn't make the request
913 sipserver_uri=NULL;
914 return 2;
915 }
916
917 not_found=1;
918 while ((row = mysql_fetch_row(res)) != NULL)
919 {
920 *sipserverurilen=strlen(row[0]);
921 if(*sipserverurilen>4)
922 {
923 CHECK_MALLOC(*sipserver_uri=malloc(*sipserverurilen+1));
924 strcpy((char *)*sipserver_uri,row[0]);
925 not_found=0;
926 break;
927 }
928 }
929 mysql_free_result(res);
930 free(query);
931 free(sipaor_pure);
932 break;
933
934 default:
935
936 //We must never go here, if so, we must stop diameter_sip
937 TRACE_DEBUG(INFO,"FATAL ERROR: the datasource is unknown, please check your config file!");
938 sipserver_uri=NULL;
939 return 2;
940
941 break;
942 }
943
944 //0 if it was found
945 return not_found;
946
947}
948
949
950int count_avp(struct msg * message, int code, int vendor)
951{
952 CHECK_PARAMS(message);
953
954 struct avp_hdr *temphdr;
955 struct avp *avp;
956 int counter=0;
957
958 CHECK_FCT(fd_msg_browse (message, MSG_BRW_WALK, &avp, NULL));
959
960 while(avp!=NULL)
961 {
962
963 CHECK_FCT( fd_msg_avp_hdr( avp,&temphdr ));
964
965 if(temphdr->avp_code==code && temphdr->avp_vendor==vendor)
966 {
967 counter++;
968 }
969
970 CHECK_FCT(fd_msg_browse (avp, MSG_BRW_WALK, &avp, NULL));
971 }
972 return counter;
973}
974/*
975void nonce_add_element(char * nonce)
976{
977 noncechain *newelt=malloc(sizeof(noncechain));
978
979 newelt->nonce=nonce;
980
981 newelt->timestamp=(int)time(NULL);
982 newelt->next=NULL;
983
984 if(listnonce==NULL)
985 {
986 listnonce=newelt;
987 }
988 else
989 {
990 noncechain* temp=listnonce;
991
992 while(temp->next != NULL)
993 {
994 if(temp->timestamp < ((int)time(NULL)-300))
995 {
996 listnonce=temp->next;
997 free(temp);
998 temp=listnonce;
999 }
1000 temp = temp->next;
1001 }
1002 temp->next = newelt;
1003 }
1004
1005}
1006void nonce_del_element(char * nonce)
1007{
1008 if(listnonce!=NULL)
1009 {
1010 noncechain *temp=listnonce, *tempbefore=NULL;
1011
1012 if(listnonce->next==NULL && strcmp(listnonce->nonce,nonce)==0)
1013 {
1014 free(listnonce);
1015 listnonce=NULL;
1016 return;
1017 }
1018 while(temp->next != NULL)
1019 {
1020 if(strcmp(temp->nonce,nonce)==0)
1021 {
1022 if(tempbefore==NULL)
1023 {
1024 listnonce=temp->next;
1025 free(temp);
1026 return;
1027 }
1028 tempbefore->next=temp->next;
1029 free(temp);
1030 break;
1031 }
1032 tempbefore=temp;
1033 temp = temp->next;
1034 }
1035
1036 }
1037
1038}
1039int nonce_check_element(char * nonce)
1040{
1041 if(listnonce==NULL)
1042 {
1043 //Not found
1044 return 0;
1045 }
1046 else
1047 {
1048 noncechain* temp=listnonce;
1049
1050 while(temp->next != NULL)
1051 {
1052 if(strcmp(temp->nonce,nonce)==0)
1053 return 1;
1054 else
1055 temp = temp->next;
1056 }
1057 }
1058 return 0;
1059}
1060
1061void nonce_deletelistnonce()
1062{
1063 if(listnonce !=NULL)
1064 {
1065 noncechain* temp=listnonce;
1066
1067 while(listnonce->next != NULL)
1068 {
1069 temp = listnonce->next;
1070
1071 free(listnonce);
1072
1073 listnonce=temp;
1074 }
1075 free(listnonce);
1076 }
1077}
1078*/