Browse code

- introduced sphere and validity check support in permission rules processing ; made presence privacy preferences compliant with RFC4745 and RFC5025

git-svn-id: https://openser.svn.sourceforge.net/svnroot/openser/trunk@3744 689a6050-402a-0410-94f2-e92a70836424

Anca Vamanu authored on 22/02/2008 14:18:50
Showing 20 changed files
... ...
@@ -35,6 +35,7 @@ Anca-Maria Vamanu
35 35
               1.3.11. fallback2db (int)
36 36
               1.3.12. subs_htable_size (int)
37 37
               1.3.13. pres_htable_size (int)
38
+              1.3.14. enable_sphere_check (int)
38 39
 
39 40
         1.4. Exported Functions
40 41
 
... ...
@@ -61,6 +62,7 @@ Anca-Maria Vamanu
61 62
         2.10. contains_event
62 63
         2.11. get_event_list
63 64
         2.12. update_watchers_status
65
+        2.13. get_sphere
64 66
 
65 67
    3. Frequently Asked Questions
66 68
 
... ...
@@ -78,8 +80,9 @@ Anca-Maria Vamanu
78 80
    1-11. Set fallback2db parameter
79 81
    1-12. Set subs_htable_size parameter
80 82
    1-13. Set pres_htable_size parameter
81
-   1-14. handle_publish usage
82
-   1-15. handle_subscribe usage
83
+   1-14. Set enable_sphere_check parameter
84
+   1-15. handle_publish usage
85
+   1-16. handle_subscribe usage
83 86
    2-1. presence_api_t structure
84 87
      __________________________________________________________
85 88
 
... ...
@@ -303,6 +306,23 @@ modparam("presence", "pres_htable_size", 11)
303 306
 ...
304 307
      __________________________________________________________
305 308
 
309
+1.3.14. enable_sphere_check (int)
310
+
311
+   This parameter is a flag that should be set if permission rules
312
+   include sphere checking. The sphere information is expected to
313
+   be present in the RPID body published by the presentity. The
314
+   flag is introduced as this check requires extra processing that
315
+   should be avoided if this feature is not supported by the
316
+   clients.
317
+
318
+   Default value is "0 ".
319
+
320
+   Example 1-14. Set enable_sphere_check parameter
321
+...
322
+modparam("presence", "enable_sphere_check", 1)
323
+...
324
+     __________________________________________________________
325
+
306 326
 1.4. Exported Functions
307 327
 
308 328
 1.4.1. handle_publish(char* sender_uri)
... ...
@@ -328,7 +348,7 @@ modparam("presence", "pres_htable_size", 11)
328 348
 
329 349
    The module sends an appropriate stateless reply in all cases.
330 350
 
331
-   Example 1-14. handle_publish usage
351
+   Example 1-15. handle_publish usage
332 352
 ...
333 353
         if(is_method("PUBLISH"))
334 354
         {
... ...
@@ -357,7 +377,7 @@ modparam("presence", "pres_htable_size", 11)
357 377
 
358 378
    The module sends an appropriate stateless reply in all cases.
359 379
 
360
-   Example 1-15. handle_subscribe usage
380
+   Example 1-16. handle_subscribe usage
361 381
 ...
362 382
 if(method=="SUBSCRIBE")
363 383
     handle_subscribe();
... ...
@@ -441,6 +461,8 @@ typedef struct presence_api {
441 461
         /* function to extract dialog information from a
442 462
         SUBSCRIBE message */
443 463
         extract_sdialog_info_t extract_sdialog_info;
464
+        /* function to request sphere defition for a presentity */
465
+        pres_get_sphere_t get_sphere;
444 466
 
445 467
 }presence_api_t;
446 468
 ...
... ...
@@ -630,6 +652,19 @@ str* rules_doc);
630 652
    document).
631 653
      __________________________________________________________
632 654
 
655
+2.13. get_sphere
656
+
657
+   Field type:
658
+...
659
+typedef char* (*pres_get_sphere_t)(str* pres_uri);
660
+...
661
+
662
+   This function searches for a sphere definition in the published
663
+   information if this has type RPID. If not found returns NULL.
664
+   (the return value is allocated in private memory and should be
665
+   freed)
666
+     __________________________________________________________
667
+
633 668
 Chapter 3. Frequently Asked Questions
634 669
 
635 670
    3.1. Where can I find more about OpenSER?
... ...
@@ -54,6 +54,7 @@ int bind_presence(presence_api_t* api)
54 54
 	api->mem_copy_subs= mem_copy_subs;
55 55
 	api->update_db_subs= update_db_subs;
56 56
 	api->extract_sdialog_info= extract_sdialog_info;
57
+	api->get_sphere= get_sphere;
57 58
 	return 0;
58 59
 }
59 60
 
... ...
@@ -31,6 +31,7 @@
31 31
 
32 32
 #include "event_list.h"
33 33
 #include "hash.h"
34
+#include "presentity.h"
34 35
 
35 36
 typedef int (*update_watchers_t)(str pres_uri, pres_ev_t* ev, str* rules_doc);
36 37
 
... ...
@@ -50,6 +51,7 @@ typedef struct presence_api {
50 51
 	mem_copy_subs_t  mem_copy_subs;
51 52
 	update_db_subs_t update_db_subs;
52 53
 	extract_sdialog_info_t extract_sdialog_info;
54
+	pres_get_sphere_t get_sphere;
53 55
 } presence_api_t;
54 56
 
55 57
 int bind_presence(presence_api_t* api);
... ...
@@ -49,6 +49,8 @@ typedef struct presence_api {
49 49
 	/* function to extract dialog information from a
50 50
 	SUBSCRIBE message */
51 51
 	extract_sdialog_info_t extract_sdialog_info;
52
+	/* function to request sphere defition for a presentity */
53
+	pres_get_sphere_t get_sphere;
52 54
 
53 55
 }presence_api_t;
54 56
 ...
... ...
@@ -317,6 +319,24 @@ str* rules_doc);
317 319
 	</para>
318 320
 </section>
319 321
 
322
+<section>
323
+	<title>
324
+	<function moreinfo="none">get_sphere</function>
325
+	</title>
326
+	<para>
327
+		Field type:
328
+		<programlisting format="linespecific">
329
+...
330
+typedef char* (*pres_get_sphere_t)(str* pres_uri);
331
+...
332
+	</para>
333
+	<para>
334
+	This function searches for a sphere definition in the published information
335
+	if this has type RPID. If not found returns NULL. (the return value is
336
+	allocated in private memory and should be freed)
337
+	</para>
338
+</section>
339
+
320 340
 </chapter>
321 341
 
322 342
 <!-- Keep this element at the end of the file
... ...
@@ -331,6 +331,29 @@ modparam("presence", "subs_htable_size", 11)
331 331
 		<programlisting format="linespecific">
332 332
 ...
333 333
 modparam("presence", "pres_htable_size", 11)
334
+...
335
+	</programlisting>
336
+		</example>
337
+	</section>
338
+	<section>
339
+		<title><varname>enable_sphere_check</varname> (int)</title>
340
+		<para>
341
+		This parameter is a flag that should be set if permission rules include
342
+		sphere checking.
343
+		The sphere information is expected to be present in the RPID body
344
+		published by the presentity. The flag is introduced as this check requires
345
+		extra processing that should be avoided if this feature is not supported
346
+		by the clients.
347
+		</para>
348
+		<para>
349
+		<emphasis>Default value is <quote>0 </quote>.
350
+		</emphasis>
351
+		</para>
352
+		<example>
353
+		<title>Set <varname>enable_sphere_check</varname> parameter</title>
354
+		<programlisting format="linespecific">
355
+...
356
+modparam("presence", "enable_sphere_check", 1)
334 357
 ...
335 358
 	</programlisting>
336 359
 		</example>
... ...
@@ -357,6 +357,8 @@ void destroy_phtable(void)
357 357
 		{
358 358
 			prev_p= p;
359 359
 			p= p->next;
360
+			if(prev_p->sphere)
361
+				shm_free(prev_p->sphere);
360 362
 			shm_free(prev_p);
361 363
 		}
362 364
 	}
... ...
@@ -380,7 +382,7 @@ pres_entry_t* search_phtable(str* pres_uri,int event, unsigned int hash_code)
380 382
 	return NULL;
381 383
 }
382 384
 
383
-int insert_phtable(str* pres_uri, int event)
385
+int insert_phtable(str* pres_uri, int event, char* sphere)
384 386
 {
385 387
 	unsigned int hash_code;
386 388
 	pres_entry_t* p= NULL;
... ...
@@ -398,6 +400,7 @@ int insert_phtable(str* pres_uri, int event)
398 400
 		return 0;
399 401
 	}
400 402
 	size= sizeof(pres_entry_t)+ pres_uri->len* sizeof(char);
403
+
401 404
 	p= (pres_entry_t*)shm_malloc(size);
402 405
 	if(p== NULL)
403 406
 	{
... ...
@@ -410,8 +413,20 @@ int insert_phtable(str* pres_uri, int event)
410 413
 	p->pres_uri.s= (char*)p+ size;
411 414
 	memcpy(p->pres_uri.s, pres_uri->s, pres_uri->len);
412 415
 	p->pres_uri.len= pres_uri->len;
413
-	 
416
+	
417
+	if(sphere)
418
+	{
419
+		p->sphere= (char*)shm_malloc(strlen(sphere)*sizeof(char));
420
+		if(p->sphere== NULL)
421
+		{
422
+			lock_release(&pres_htable[hash_code].lock);
423
+			ERR_MEM(SHARE_MEM);
424
+		}
425
+		strcpy(p->sphere, sphere);
426
+	}
427
+
414 428
 	p->event= event;
429
+	
415 430
 
416 431
 	p->next= pres_htable[hash_code].entries->next;
417 432
 	pres_htable[hash_code].entries->next= p;
... ...
@@ -459,9 +474,60 @@ int delete_phtable(str* pres_uri, int event)
459 474
 			return -1;
460 475
 		}
461 476
 		prev_p->next= p->next;
477
+		if(p->sphere)
478
+			shm_free(p->sphere);
479
+
462 480
 		shm_free(p);
463 481
 	}
464 482
 	lock_release(&pres_htable[hash_code].lock);
465 483
 
466 484
 	return 0;	
467 485
 }
486
+
487
+int update_phtable(presentity_t* presentity, str pres_uri, str body)
488
+{
489
+	char* sphere;
490
+	unsigned int hash_code;
491
+	pres_entry_t* p;
492
+	int ret= 0;
493
+
494
+	/* get new sphere */
495
+	sphere= extract_sphere(body);
496
+	if(sphere==NULL)
497
+	{
498
+		LM_DBG("no sphere defined in new body\n");
499
+		return 0;
500
+	}
501
+
502
+	/* search for record in hash table */
503
+	hash_code= core_hash(&pres_uri, NULL, phtable_size);
504
+	
505
+	lock_get(&pres_htable[hash_code].lock);
506
+
507
+	p= search_phtable(&pres_uri, presentity->event->evp->parsed, hash_code);
508
+	if(p== NULL)
509
+	{
510
+		lock_release(&pres_htable[hash_code].lock);
511
+		goto done;
512
+	}
513
+	
514
+	if(p->sphere)
515
+		shm_free(p->sphere);
516
+
517
+	p->sphere= (char*)shm_malloc(strlen(sphere)*sizeof(char));
518
+	if(p->sphere== NULL)
519
+	{
520
+		lock_release(&pres_htable[hash_code].lock);
521
+		ret= -1;
522
+		goto done;
523
+	}
524
+	strcpy(p->sphere, sphere);
525
+		
526
+	lock_release(&pres_htable[hash_code].lock);
527
+		
528
+done:
529
+
530
+	if(sphere)
531
+		pkg_free(sphere);
532
+	return ret;
533
+}
... ...
@@ -31,7 +31,9 @@
31 31
 #define PS_HASH_H
32 32
 
33 33
 #include "../../lock_ops.h"
34
+//#include "presentity.h"
34 35
 
36
+struct presentity;
35 37
 #define REMOTE_TYPE   1<<1
36 38
 #define LOCAL_TYPE    1<<2
37 39
 
... ...
@@ -105,6 +107,7 @@ typedef struct pres_entry
105 107
 	str pres_uri;
106 108
 	int event;
107 109
 	int publ_count;
110
+	char* sphere;
108 111
 	struct pres_entry* next;
109 112
 }pres_entry_t;
110 113
 
... ...
@@ -118,7 +121,9 @@ phtable_t* new_phtable(void);
118 121
 
119 122
 pres_entry_t* search_phtable(str* pres_uri, int event, unsigned int hash_code);
120 123
 
121
-int insert_phtable(str* pres_uri, int event);
124
+int insert_phtable(str* pres_uri, int event, char* sphere);
125
+
126
+int update_phtable(struct presentity* presentity, str pres_uri, str body);
122 127
 
123 128
 int delete_phtable(str* pres_uri, int event);
124 129
 
... ...
@@ -27,6 +27,7 @@
27 27
  */
28 28
 
29 29
 #include "../../str.h"
30
+#include "../tm/dlg.h"
30 31
 #include "subscribe.h"
31 32
 #include "presentity.h"
32 33
 
... ...
@@ -98,6 +98,7 @@ int stored_pres_info(struct sip_msg* msg, char* pres_uri, char* s);
98 98
 static int fixup_presence(void** param, int param_no);
99 99
 static struct mi_root* mi_refreshWatchers(struct mi_root* cmd, void* param);
100 100
 static int update_pw_dialogs(subs_t* subs, unsigned int hash_code, subs_t** subs_array);
101
+int update_watchers_status(str pres_uri, pres_ev_t* ev, str* rules_doc);
101 102
 static int mi_child_init(void);
102 103
 
103 104
 int counter =0;
... ...
@@ -110,6 +111,7 @@ int max_expires= 3600;
110 111
 int shtable_size= 9;
111 112
 shtable_t subs_htable= NULL;
112 113
 int fallback2db= 0;
114
+int sphere_enable= 0;
113 115
 
114 116
 int phtable_size= 9;
115 117
 phtable_t* pres_htable;
... ...
@@ -137,6 +139,7 @@ static param_export_t params[]={
137 139
 	{ "subs_htable_size",       INT_PARAM, &shtable_size},
138 140
 	{ "pres_htable_size",       INT_PARAM, &phtable_size},
139 141
 	{ "fallback2db",            INT_PARAM, &fallback2db},
142
+	{ "enable_sphere_check",    INT_PARAM, &sphere_enable},
140 143
 	{0,0,0}
141 144
 };
142 145
 
... ...
@@ -61,6 +61,7 @@ extern struct sl_binds slb;
61 61
 extern str server_address;
62 62
 extern int max_expires;
63 63
 extern int fallback2db;
64
+extern int sphere_enable;
64 65
 
65 66
 extern int shtable_size;
66 67
 extern shtable_t subs_htable;
... ...
@@ -45,6 +45,8 @@
45 45
 #include "utils_func.h"
46 46
 
47 47
 
48
+xmlNodePtr xmlNodeGetNodeByName(xmlNodePtr node, const char *name,
49
+													const char *ns);
48 50
 static str pu_200_rpl  = str_init("OK");
49 51
 static str pu_412_rpl  = str_init("Conditional request failed");
50 52
 
... ...
@@ -223,7 +225,7 @@ error:
223 225
 }
224 226
 
225 227
 int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body,
226
-		int new_t, int* sent_reply)
228
+		int new_t, int* sent_reply, char* sphere)
227 229
 {
228 230
 	db_key_t query_cols[11], update_keys[7], result_cols[5];
229 231
 	db_op_t  query_ops[11];
... ...
@@ -290,7 +292,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body,
290 292
 	{
291 293
 		/* insert new record in hash_table */
292 294
 	
293
-		if(insert_phtable(&pres_uri, presentity->event->evp->parsed)< 0)
295
+		if(insert_phtable(&pres_uri, presentity->event->evp->parsed, sphere)< 0)
294 296
 		{
295 297
 			LM_ERR("inserting record in hash table\n");
296 298
 			goto error;
... ...
@@ -464,6 +466,17 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body,
464 466
 				update_vals[n_update_cols].nul = 0;
465 467
 				update_vals[n_update_cols].val.str_val = *body;
466 468
 				n_update_cols++;
469
+
470
+				/* updated stored sphere */
471
+				if(sphere_enable && 
472
+						presentity->event->evp->parsed== EVENT_PRESENCE)
473
+				{
474
+					if(update_phtable(presentity, pres_uri, *body)< 0)
475
+					{
476
+						LM_ERR("failed to update sphere for presentity\n");
477
+						goto error;
478
+					}
479
+				}
467 480
 			}
468 481
 
469 482
 			if( pa_dbf.update( pa_db,query_cols, query_ops, query_vals,
... ...
@@ -547,22 +560,25 @@ int pres_htable_restore(void)
547 560
 {
548 561
 	/* query all records from presentity table and insert records 
549 562
 	 * in presentity table */
550
-	db_key_t result_cols[5];
563
+	db_key_t result_cols[6];
551 564
 	db_res_t *result= NULL;
552 565
 	db_row_t *row= NULL ;	
553 566
 	db_val_t *row_vals;
554 567
 	int  i;
555
-	str user, domain, ev_str, uri;
568
+	str user, domain, ev_str, uri, body;
556 569
 	int n_result_cols= 0;
557
-	int user_col, domain_col, event_col, expires_col;
570
+	int user_col, domain_col, event_col, expires_col, body_col;
558 571
 	int event;
559 572
 	event_t ev;
573
+	char* sphere= NULL;
560 574
 
561 575
 	result_cols[user_col= n_result_cols++]= &str_username_col;
562 576
 	result_cols[domain_col= n_result_cols++]= &str_domain_col;
563 577
 	result_cols[event_col= n_result_cols++]= &str_event_col;
564 578
 	result_cols[expires_col= n_result_cols++]= &str_expires_col;
565
-	
579
+	if(sphere_enable)
580
+		result_cols[body_col= n_result_cols++]= &str_body_col;
581
+
566 582
 	if (pa_dbf.use_table(pa_db, &presentity_table) < 0)
567 583
 	{
568 584
 		LM_ERR("unsuccessful use table sql operation\n");
... ...
@@ -591,14 +607,15 @@ int pres_htable_restore(void)
591 607
 
592 608
 		if(row_vals[expires_col].val.int_val< (int)time(NULL))
593 609
 			continue;
594
-
610
+		
611
+		sphere= NULL;
595 612
 		user.s= (char*)row_vals[user_col].val.string_val;
596 613
 		user.len= strlen(user.s);
597 614
 		domain.s= (char*)row_vals[domain_col].val.string_val;
598 615
 		domain.len= strlen(domain.s);
599 616
 		ev_str.s= (char*)row_vals[event_col].val.string_val;
600 617
 		ev_str.len= strlen(ev_str.s);
601
-	
618
+
602 619
 		if(event_parser(ev_str.s, ev_str.len, &ev)< 0)
603 620
 		{
604 621
 			LM_ERR("parsing event\n");
... ...
@@ -614,12 +631,24 @@ int pres_htable_restore(void)
614 631
 			goto error;
615 632
 		}
616 633
 		/* insert in hash_table*/
617
-		if(insert_phtable(&uri, event)< 0)
634
+	
635
+		if(sphere_enable && event== EVENT_PRESENCE )
636
+		{
637
+			body.s= (char*)row_vals[body_col].val.string_val;
638
+			body.len= strlen(body.s);
639
+			sphere= extract_sphere(body);
640
+		}
641
+
642
+		if(insert_phtable(&uri, event, sphere)< 0)
618 643
 		{
619 644
 			LM_ERR("inserting record in presentity hash table");
620 645
 			pkg_free(uri.s);
646
+			if(sphere)
647
+				pkg_free(sphere);
621 648
 			goto error;
622 649
 		}
650
+		if(sphere)
651
+			pkg_free(sphere);
623 652
 		pkg_free(uri.s);
624 653
 	}
625 654
 	pa_dbf.free_result(pa_db, result);
... ...
@@ -631,3 +660,190 @@ error:
631 660
 		pa_dbf.free_result(pa_db, result);
632 661
 	return -1;	
633 662
 }
663
+
664
+char* extract_sphere(str body)
665
+{
666
+
667
+	/* check for a rpid sphere element */
668
+	xmlDocPtr doc= NULL;
669
+	xmlNodePtr node;
670
+	char* cont, *sphere= NULL;
671
+	
672
+
673
+	doc= xmlParseMemory(body.s, body.len);
674
+	if(doc== NULL)
675
+	{
676
+		LM_ERR("failed to parse xml body\n");
677
+		return NULL;
678
+	}
679
+
680
+	node= xmlNodeGetNodeByName(doc->children, "sphere", "rpid");
681
+	if(node)
682
+	{
683
+		LM_DBG("found sphere definition\n");
684
+		cont= (char*)xmlNodeGetContent(node);
685
+		sphere= (char*)pkg_malloc(strlen(cont)*sizeof(char));
686
+		if(sphere== NULL)
687
+		{
688
+			xmlFree(cont);
689
+			ERR_MEM(PKG_MEM_STR);
690
+		}
691
+		xmlFree(cont);
692
+		strcpy(sphere, cont);
693
+	}
694
+	else
695
+		LM_DBG("didn't find sphere definition\n");
696
+
697
+error:
698
+	xmlFreeDoc(doc);
699
+
700
+	return sphere;
701
+}
702
+
703
+xmlNodePtr xmlNodeGetNodeByName(xmlNodePtr node, const char *name,
704
+													const char *ns)
705
+{
706
+	xmlNodePtr cur = node;
707
+	while (cur) {
708
+		xmlNodePtr match = NULL;
709
+		if (xmlStrcasecmp(cur->name, (unsigned char*)name) == 0) {
710
+			if (!ns || (cur->ns && xmlStrcasecmp(cur->ns->prefix,
711
+							(unsigned char*)ns) == 0))
712
+				return cur;
713
+		}
714
+		match = xmlNodeGetNodeByName(cur->children, name, ns);
715
+		if (match)
716
+			return match;
717
+		cur = cur->next;
718
+	}
719
+	return NULL;
720
+}
721
+
722
+char* get_sphere(str* pres_uri)
723
+{
724
+	unsigned int hash_code;
725
+	char* sphere= NULL;
726
+	pres_entry_t* p;
727
+	db_key_t query_cols[6];
728
+	db_val_t query_vals[6];
729
+	db_key_t result_cols[6];
730
+	db_res_t *result = NULL;
731
+	db_row_t *row= NULL ;	
732
+	db_val_t *row_vals;
733
+	int n_result_cols = 0;
734
+	int n_query_cols = 0;
735
+	struct sip_uri uri;
736
+	str body;
737
+
738
+	/* search in hash table*/
739
+	hash_code= core_hash(pres_uri, NULL, phtable_size);
740
+
741
+	lock_get(&pres_htable[hash_code].lock);
742
+
743
+	p= search_phtable(pres_uri, EVENT_PRESENCE, hash_code);
744
+
745
+	if(p)
746
+	{
747
+		if(p->sphere)
748
+		{
749
+			sphere= (char*)pkg_malloc(strlen(p->sphere)* sizeof(char));
750
+			if(sphere== NULL)
751
+			{
752
+				lock_release(&pres_htable[hash_code].lock);
753
+				ERR_MEM(PKG_MEM_STR);
754
+			}
755
+			strcpy(sphere, p->sphere);
756
+		}
757
+		lock_release(&pres_htable[hash_code].lock);
758
+		return sphere;
759
+	}
760
+	lock_release(&pres_htable[hash_code].lock);
761
+
762
+
763
+	/* if record not found and fallback2db query database*/
764
+	if(!fallback2db)
765
+	{
766
+		return NULL;
767
+	}
768
+
769
+	if(parse_uri(pres_uri->s, pres_uri->len, &uri)< 0)
770
+	{
771
+		LM_ERR("failed to parse presentity uri\n");
772
+		goto error;
773
+	}
774
+
775
+	query_cols[n_query_cols] = &str_domain_col;
776
+	query_vals[n_query_cols].type = DB_STR;
777
+	query_vals[n_query_cols].nul = 0;
778
+	query_vals[n_query_cols].val.str_val = uri.host;
779
+	n_query_cols++;
780
+
781
+	query_cols[n_query_cols] = &str_username_col;
782
+	query_vals[n_query_cols].type = DB_STR;
783
+	query_vals[n_query_cols].nul = 0;
784
+	query_vals[n_query_cols].val.str_val = uri.user;
785
+	n_query_cols++;
786
+
787
+	query_cols[n_query_cols] = &str_event_col;
788
+	query_vals[n_query_cols].type = DB_STR;
789
+	query_vals[n_query_cols].nul = 0;
790
+	query_vals[n_query_cols].val.str_val.s= "presence";
791
+	query_vals[n_query_cols].val.str_val.len= 8;
792
+	n_query_cols++;
793
+
794
+	result_cols[n_result_cols++] = &str_body_col;
795
+	
796
+	if (pa_dbf.use_table(pa_db, &presentity_table) < 0) 
797
+	{
798
+		LM_ERR("in use_table\n");
799
+		return NULL;
800
+	}
801
+
802
+	static str query_str = str_init("received_time");
803
+	if (pa_dbf.query (pa_db, query_cols, 0, query_vals,
804
+		 result_cols, n_query_cols, n_result_cols, &query_str ,  &result) < 0) 
805
+	{
806
+		LM_ERR("failed to query %.*s table\n", presentity_table.len, presentity_table.s);
807
+		if(result)
808
+			pa_dbf.free_result(pa_db, result);
809
+		return NULL;
810
+	}
811
+	
812
+	if(result== NULL)
813
+		return NULL;
814
+
815
+	if (result->n<=0 )
816
+	{
817
+		LM_DBG("no published record found in database\n");
818
+		pa_dbf.free_result(pa_db, result);
819
+		return NULL;
820
+	}
821
+
822
+	row = &result->rows[result->n-1];
823
+	row_vals = ROW_VALUES(row);
824
+	if(row_vals[0].val.string_val== NULL)
825
+	{
826
+		LM_ERR("NULL notify body record\n");
827
+		goto error;
828
+	}
829
+
830
+	body.s= (char*)row_vals[0].val.string_val;
831
+	body.len= strlen(body.s);
832
+	if(body.len== 0)
833
+	{
834
+		LM_ERR("Empty notify body record\n");
835
+		goto error;
836
+	}
837
+	
838
+	sphere= extract_sphere(body);
839
+
840
+	pa_dbf.free_result(pa_db, result);
841
+	return sphere;
842
+
843
+
844
+error:
845
+	if(result)
846
+		pa_dbf.free_result(pa_db, result);
847
+	return NULL;
848
+
849
+}
... ...
@@ -29,16 +29,10 @@
29 29
 #ifndef PRESENTITY_H
30 30
 #define PRESENTITY_H
31 31
 
32
-#include <stdio.h>
33
-#include <stdlib.h>
34
-#include <string.h>
35
-
36
-#include <libxml/parser.h>
37
-#include <time.h>
38 32
 #include "../../str.h"
39 33
 #include "../../parser/msg_parser.h" 
40 34
 #include "event_list.h"
41
-#include "presence.h"
35
+//#include "presence.h"
42 36
 
43 37
 extern char prefix;
44 38
 
... ...
@@ -60,7 +54,7 @@ presentity_t* new_presentity( str* domain,str* user,int expires,
60 54
 
61 55
 /* update presentity in database */
62 56
 int update_presentity(struct sip_msg* msg,presentity_t* p,str* body,int t_new,
63
-		int* sent_reply);
57
+		int* sent_reply, char* sphere);
64 58
 
65 59
 /* free memory */
66 60
 void free_presentity(presentity_t* p);
... ...
@@ -69,5 +63,11 @@ char* generate_ETag(int publ_count);
69 63
 
70 64
 int pres_htable_restore(void);
71 65
 
66
+char* extract_sphere(str body);
67
+
68
+char* get_sphere(str* pres_uri);
69
+typedef char* (*pres_get_sphere_t)(str* pres_uri);
70
+
71
+
72 72
 #endif
73 73
 
... ...
@@ -293,6 +293,7 @@ int handle_publish(struct sip_msg* msg, char* sender_uri, char* str2)
293 293
 	int reply_code;
294 294
 	str reply_str;
295 295
 	int sent_reply= 0;
296
+	char* sphere= NULL;
296 297
 
297 298
 	reply_code= 500;
298 299
 	reply_str= pu_500_rpl;
... ...
@@ -435,6 +436,13 @@ int handle_publish(struct sip_msg* msg, char* sender_uri, char* str2)
435 436
 			goto error;
436 437
 		}
437 438
 		body.len= get_content_length( msg );
439
+
440
+		if(sphere_enable && event->evp->parsed & EVENT_PRESENCE &&
441
+				get_content_type(msg)== SUBTYPE_PIDFXML)
442
+		{
443
+			sphere= extract_sphere(body);			
444
+		}
445
+
438 446
 	}	
439 447
 	memset(&puri, 0, sizeof(struct sip_uri));
440 448
 	if(sender_uri)
... ...
@@ -485,7 +493,7 @@ int handle_publish(struct sip_msg* msg, char* sender_uri, char* str2)
485 493
 	}
486 494
 
487 495
 	/* querry the database and update or insert */
488
-	if(update_presentity(msg, presentity, &body, etag_gen, &sent_reply) <0)
496
+	if(update_presentity(msg, presentity, &body, etag_gen, &sent_reply, sphere) <0)
489 497
 	{
490 498
 		LM_ERR("when updating presentity\n");
491 499
 		goto error;
... ...
@@ -497,6 +505,8 @@ int handle_publish(struct sip_msg* msg, char* sender_uri, char* str2)
497 505
 		pkg_free(etag.s);
498 506
 	if(sender)
499 507
 		pkg_free(sender);
508
+	if(sphere)
509
+		pkg_free(sphere);
500 510
 
501 511
 	return 1;
502 512
 
... ...
@@ -525,6 +535,8 @@ error:
525 535
 		pkg_free(etag.s);
526 536
 	if(sender)
527 537
 		pkg_free(sender);
538
+	if(sphere)
539
+		pkg_free(sphere);
528 540
 
529 541
 	return -1;
530 542
 
... ...
@@ -53,8 +53,9 @@ Chapter 1. User's Guide
53 53
    module, presence. It constructs and adds 3 events to it:
54 54
    presence, presence.winfo, dialog;sla.
55 55
 
56
-   This module uses xcap_table with permission rules to deal with
57
-   authorization rules for presence.
56
+   This module takes the xcap permission rule documents from
57
+   xcap_table. The presence permission rules are interpreted
58
+   according to the specifications in RFC 4745 and RFC 5025.
58 59
      __________________________________________________________
59 60
 
60 61
 1.2. Dependencies
... ...
@@ -19,8 +19,10 @@
19 19
 	3 events to it: presence, presence.winfo, dialog;sla. 
20 20
 	</para>
21 21
 	<para>
22
-	This module uses xcap_table with permission rules to deal with authorization rules 
23
-	for presence.
22
+	This module takes the xcap permission rule documents from xcap_table.
23
+
24
+	The presence permission rules are interpreted according to the specifications
25
+	in RFC 4745 and RFC 5025.
24 26
 	</para>
25 27
 	<para>
26 28
 	</section>
... ...
@@ -25,7 +25,9 @@
25 25
  * --------
26 26
  *  2007-04-14  initial version (anca)
27 27
  */
28
+#define _XOPEN_SOURCE
28 29
 
30
+#include <time.h>
29 31
 #include <string.h>
30 32
 #include <stdlib.h>
31 33
 #include <libxml/parser.h>
... ...
@@ -108,3 +110,68 @@ char *xmlDocGetNodeContentByName(xmlDocPtr doc, const char *name,
108 110
 	else
109 111
 		return NULL;
110 112
 }
113
+
114
+time_t xml_parse_dateTime(char* xml_time_str)
115
+{
116
+	struct tm tm;
117
+	char * p;
118
+	int h, m;
119
+	char h1, h2, m1, m2;
120
+	int sign= 1;
121
+	signed int timezone_diff= 0;
122
+
123
+	p= strptime(xml_time_str, "%F", &tm);
124
+	if(p== NULL)
125
+	{
126
+		printf("error: failed to parse time\n");
127
+		return 0;
128
+	}
129
+	p++;
130
+	p= strptime(p, "%T", &tm);
131
+	if(p== NULL)
132
+	{
133
+		printf("error: failed to parse time\n");
134
+		return 0;
135
+	}
136
+	
137
+	if(*p== '\0')
138
+		goto done;
139
+
140
+	if(*p== '.')
141
+	{
142
+		p++;
143
+		/* read the fractionar part of the seconds*/
144
+		while(*p!= '\0' && *p>= '0' && *p<= '9')
145
+		{
146
+			p++;
147
+		}
148
+	}
149
+
150
+	if(*p== '\0')
151
+		goto done;
152
+
153
+	
154
+	/* read time zone */
155
+
156
+	if(*p== 'Z')
157
+	{
158
+		goto done;
159
+	}
160
+
161
+	if(*p== '+')
162
+		sign= -1;
163
+
164
+	p++;
165
+
166
+	sscanf(p, "%c%c:%c%c", &h1, &h2, &m1, &m2);
167
+	
168
+	h= (h1- '0')*10+ h2- '0';
169
+	m= (m1- '0')*10+ m2- '0';
170
+
171
+	timezone_diff= sign* ((m+ h* 60)* 60);
172
+
173
+done:
174
+	return (mktime(&tm) + timezone_diff);	
175
+}
176
+
177
+
... ...
@@ -41,5 +41,6 @@ char *xmlNodeGetNodeContentByName(xmlNodePtr root, const char *name,
41 41
 		const char *ns);
42 42
 char *xmlNodeGetAttrContentByName(xmlNodePtr node, const char *name);
43 43
 
44
+time_t xml_parse_dateTime(char* xml_time_str);
44 45
 
45 46
 #endif 
... ...
@@ -66,6 +66,8 @@ static struct mi_root* dum(struct mi_root* cmd, void* param);
66 66
 /** module variables ***/
67 67
 add_event_t pres_add_event;
68 68
 update_watchers_t pres_update_watchers;
69
+pres_get_sphere_t pres_get_sphere;
70
+
69 71
 
70 72
 str xcap_table= str_init("xcap");
71 73
 str db_url = {0, 0};
... ...
@@ -96,7 +98,7 @@ static param_export_t params[]={
96 98
 };
97 99
 
98 100
 static mi_export_t mi_cmds[] = {
99
-	{ "dum",             dum,            0,  0,  mi_child_init},
101
+	{ "dum",             dum,          0,  0,  mi_child_init},
100 102
 	{  0,                0,            0,  0,        0      }
101 103
 };
102 104
 
... ...
@@ -174,7 +176,8 @@ static int mod_init(void)
174 176
 		LM_ERR("Can't bind module pua\n");
175 177
 		return -1;
176 178
 	}
177
-
179
+	
180
+	pres_get_sphere= pres.get_sphere;
178 181
 	pres_add_event= pres.add_event;
179 182
 	pres_update_watchers= pres.update_watchers_status;
180 183
 	if (pres_add_event == NULL || pres_update_watchers== NULL)
... ...
@@ -33,6 +33,7 @@
33 33
 #include "../sl/sl_api.h"
34 34
 #include "../presence/event_list.h"
35 35
 #include "../presence/presence.h"
36
+#include "../presence/presentity.h"
36 37
 #include "../xcap_client/xcap_functions.h"
37 38
 
38 39
 typedef struct xcap_serv
... ...
@@ -51,5 +52,6 @@ extern int pidf_manipulation;
51 52
 extern int integrated_xcap_server;
52 53
 extern xcap_serv_t* xs_list;
53 54
 extern xcapGetNewDoc_t xcap_GetNewDoc;
55
+extern pres_get_sphere_t pres_get_sphere;
54 56
 
55 57
 #endif
... ...
@@ -3,7 +3,7 @@
3 3
  *
4 4
  * presence_xml module - 
5 5
  *
6
- * Copyright (C) 2006 Voice Sistem S.R.L.
6
+ * Copyright (C) 2007 Voice Sistem S.R.L.
7 7
  *
8 8
  * This file is part of openser, a free SIP server.
9 9
  *
... ...
@@ -29,6 +29,7 @@
29 29
 #include <stdio.h>
30 30
 #include <stdlib.h>
31 31
 #include <string.h>
32
+#include <time.h>
32 33
 #include <libxml/parser.h>
33 34
 
34 35
 #include "../../str.h"
... ...
@@ -145,12 +146,16 @@ int pres_watcher_allowed(subs_t* subs)
145 146
 xmlNodePtr get_rule_node(subs_t* subs, xmlDocPtr xcap_tree )
146 147
 {
147 148
 	str w_uri= {0, 0};
148
-	char* id = NULL, *domain = NULL;
149
+	char* id = NULL, *domain = NULL, *time_cont= NULL;
149 150
 	int apply_rule = -1;
150 151
 	xmlNodePtr ruleset_node = NULL, node1= NULL, node2= NULL;
151 152
 	xmlNodePtr cond_node = NULL, except_node = NULL;
152
-	xmlNodePtr identity_node = NULL, validity_node =NULL, sphere_node = NULL;
153
+	xmlNodePtr identity_node = NULL, sphere_node = NULL;
153 154
 	xmlNodePtr iden_child;
155
+	xmlNodePtr validity_node, time_node;
156
+	time_t t_init, t_fin, t;
157
+	int valid= 0;
158
+
154 159
 
155 160
 	uandd_to_uri(subs->from_user, subs->from_domain, &w_uri);
156 161
 	if(w_uri.s == NULL)
... ...
@@ -185,9 +190,98 @@ xmlNodePtr get_rule_node(subs_t* subs, xmlDocPtr xcap_tree )
185 190
 		if(validity_node !=NULL)
186 191
 		{
187 192
 			LM_DBG("found validity tag\n");
193
+		
194
+			t= time(NULL);
195
+		
196
+			/* search all from-until pair */
197
+			for(time_node= validity_node->children; time_node;
198
+					time_node= time_node->next)
199
+			{
200
+				if(xmlStrcasecmp(time_node->name, (unsigned char*)"from")!= 0)
201
+				{
202
+					continue;
203
+				}
204
+				time_cont= (char*)xmlNodeGetContent(time_node);
205
+				t_init= xml_parse_dateTime(time_cont);
206
+				xmlFree(time_cont);
207
+				if(t_init< 0)
208
+				{
209
+					LM_ERR("failed to parse xml dateTime\n");
210
+					goto error;
211
+				}
212
+
213
+				if(t< t_init)
214
+				{
215
+					LM_DBG("the lower time limit is not respected\n");
216
+					continue;
217
+				}
218
+				
219
+				time_node= time_node->next;
220
+				while(1)
221
+				{
222
+					if(time_node== NULL)
223
+					{	
224
+						LM_ERR("bad formatted xml doc:until child not found in"
225
+								" validity pair\n");
226
+						goto error;
227
+					}
228
+					if( xmlStrcasecmp(time_node->name, 
229
+								(unsigned char*)"until")== 0)
230
+						break;
231
+					time_node= time_node->next;
232
+				}
233
+				
234
+				time_cont= (char*)xmlNodeGetContent(time_node);
235
+				t_fin= xml_parse_dateTime(time_cont);
236
+				xmlFree(time_cont);
237
+
238
+				if(t_fin< 0)
239
+				{
240
+					LM_ERR("failed to parse xml dateTime\n");
241
+					goto error;
242
+				}
243
+			
244
+				if(t <= t_fin)
245
+				{
246
+					LM_DBG("the rule is active at this time\n");
247
+					valid= 1;
248
+				}
249
+			
250
+			}
251
+		
252
+			if(!valid)
253
+			{
254
+				LM_DBG("the rule is not active at this time\n");
255
+				continue;
256
+			}
188 257
 
189 258
 		}	
259
+	
190 260
 		sphere_node = xmlNodeGetChildByName(cond_node, "sphere");
261
+		if(sphere_node!= NULL)
262
+		{
263
+			/* check to see if matches presentity current sphere */
264
+			/* ask presence for sphere information */
265
+			
266
+			char* sphere= pres_get_sphere(&subs->pres_uri);
267
+			if(sphere)
268
+			{
269
+				char* attr= (char*)xmlNodeGetContent(sphere_node);
270
+				if(xmlStrcasecmp((unsigned char*)attr, (unsigned char*)sphere)!= 0)
271
+				{
272
+					LM_DBG("sphere condition not respected\n");
273
+					pkg_free(sphere);
274
+					xmlFree(attr);
275
+					continue;
276
+				}
277
+				pkg_free(sphere);
278
+				xmlFree(attr);
279
+	
280
+			}
281
+				
282
+			/* if the user has not define a sphere -> 
283
+			 *						consider the condition true*/
284
+		}
191 285
 
192 286
 		identity_node = xmlNodeGetChildByName(cond_node, "identity");
193 287
 		if(identity_node == NULL)