00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <string.h>
00035 #include <stdlib.h>
00036 #include <libxml/parser.h>
00037
00038 #include "../../mem/mem.h"
00039 #include "../presence/utils_func.h"
00040 #include "../presence/hash.h"
00041 #include "xcap_auth.h"
00042 #include "pidf.h"
00043 #include "notify_body.h"
00044 #include "presence_xml.h"
00045
00046 str* offline_nbody(str* body);
00047 str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n);
00048 str* get_final_notify_body( subs_t *subs, str* notify_body, xmlNodePtr rule_node);
00049
00050 void free_xml_body(char* body)
00051 {
00052 if(body== NULL)
00053 return;
00054
00055 xmlFree(body);
00056 body= NULL;
00057 }
00058
00059
00060 str* pres_agg_nbody(str* pres_user, str* pres_domain, str** body_array, int n, int off_index)
00061 {
00062 str* n_body= NULL;
00063 str* body= NULL;
00064
00065 if(body_array== NULL && !pidf_manipulation)
00066 return NULL;
00067
00068 if(off_index>= 0)
00069 {
00070 body= body_array[off_index];
00071 body_array[off_index]= offline_nbody(body);
00072
00073 if(body_array[off_index]== NULL || body_array[off_index]->s== NULL)
00074 {
00075 LM_ERR("while constructing offline body\n");
00076 return NULL;
00077 }
00078 }
00079 LM_DBG("[user]=%.*s [domain]= %.*s\n",
00080 pres_user->len, pres_user->s, pres_domain->len, pres_domain->s);
00081 n_body= agregate_xmls(pres_user, pres_domain, body_array, n);
00082 if(n_body== NULL && n!= 0)
00083 {
00084 LM_ERR("while aggregating body\n");
00085 }
00086
00087 if(off_index>= 0)
00088 {
00089 xmlFree(body_array[off_index]->s);
00090 pkg_free(body_array[off_index]);
00091 body_array[off_index]= body;
00092 }
00093
00094 xmlCleanupParser();
00095 xmlMemoryDump();
00096
00097 return n_body;
00098 }
00099
00100 int pres_apply_auth(str* notify_body, subs_t* subs, str** final_nbody)
00101 {
00102 xmlDocPtr doc= NULL;
00103 xmlNodePtr node= NULL;
00104 str* n_body= NULL;
00105
00106 *final_nbody= NULL;
00107 if(force_active)
00108 return 0;
00109
00110 if(subs->auth_rules_doc== NULL)
00111 {
00112 LM_ERR("NULL rules doc\n");
00113 return -1;
00114 }
00115 doc= xmlParseMemory(subs->auth_rules_doc->s, subs->auth_rules_doc->len);
00116 if(doc== NULL)
00117 {
00118 LM_ERR("parsing xml doc\n");
00119 return -1;
00120 }
00121
00122 node= get_rule_node(subs, doc);
00123 if(node== NULL)
00124 {
00125 LM_DBG("The subscriber didn't match the conditions\n");
00126 xmlFreeDoc(doc);
00127 return 0;
00128 }
00129
00130 n_body= get_final_notify_body(subs, notify_body, node);
00131 if(n_body== NULL)
00132 {
00133 LM_ERR("in function get_final_notify_body\n");
00134 xmlFreeDoc(doc);
00135 return -1;
00136 }
00137
00138 xmlFreeDoc(doc);
00139 xmlCleanupParser();
00140 xmlMemoryDump();
00141
00142 *final_nbody= n_body;
00143 return 1;
00144
00145 }
00146
00147 str* get_final_notify_body( subs_t *subs, str* notify_body, xmlNodePtr rule_node)
00148 {
00149 xmlNodePtr transf_node = NULL, node = NULL, dont_provide = NULL;
00150 xmlNodePtr doc_root = NULL, doc_node = NULL, provide_node = NULL;
00151 xmlNodePtr all_node = NULL;
00152 xmlDocPtr doc= NULL;
00153 char name[15];
00154 char service_uri_scheme[10];
00155 int i= 0, found = 0;
00156 str* new_body = NULL;
00157 char* class_cont = NULL, *occurence_ID= NULL, *service_uri= NULL;
00158 char* deviceID = NULL;
00159 char* content = NULL;
00160 char all_name[20];
00161
00162 strcpy(all_name, "all-");
00163
00164 new_body = (str*)pkg_malloc(sizeof(str));
00165 if(new_body == NULL)
00166 {
00167 LM_ERR("while allocating memory\n");
00168 return NULL;
00169 }
00170
00171 memset(new_body, 0, sizeof(str));
00172
00173 doc = xmlParseMemory(notify_body->s, notify_body->len);
00174 if(doc== NULL)
00175 {
00176 LM_ERR("while parsing the xml body message\n");
00177 goto error;
00178 }
00179 doc_root = xmlDocGetNodeByName(doc,"presence", NULL);
00180 if(doc_root == NULL)
00181 {
00182 LM_ERR("while extracting the presence node\n");
00183 goto error;
00184 }
00185
00186 transf_node = xmlNodeGetChildByName(rule_node, "transformations");
00187 if(transf_node == NULL)
00188 {
00189 LM_DBG("transformations node not found\n");
00190 goto done;
00191 }
00192
00193 for(node = transf_node->children; node; node = node->next )
00194 {
00195 if(xmlStrcasecmp(node->name, (unsigned char*)"text")== 0)
00196 continue;
00197
00198 LM_DBG("transf_node->name:%s\n",node->name);
00199
00200 strcpy((char*)name ,(char*)(node->name + 8));
00201 strcpy(all_name+4, name);
00202
00203 if(xmlStrcasecmp((unsigned char*)name,(unsigned char*)"services") == 0)
00204 strcpy(name, "tuple");
00205 if(strncmp((char*)name,"person", 6) == 0)
00206 name[6] = '\0';
00207
00208 doc_node = xmlNodeGetNodeByName(doc_root, name, NULL);
00209 if(doc_node == NULL)
00210 continue;
00211 LM_DBG("searched doc_node->name:%s\n",name);
00212
00213 content = (char*)xmlNodeGetContent(node);
00214 if(content)
00215 {
00216 LM_DBG("content = %s\n", content);
00217
00218 if(xmlStrcasecmp((unsigned char*)content,
00219 (unsigned char*) "FALSE") == 0)
00220 {
00221 LM_DBG("found content false\n");
00222 while( doc_node )
00223 {
00224 xmlUnlinkNode(doc_node);
00225 xmlFreeNode(doc_node);
00226 doc_node = xmlNodeGetChildByName(doc_root, name);
00227 }
00228 xmlFree(content);
00229 continue;
00230 }
00231
00232 if(xmlStrcasecmp((unsigned char*)content,
00233 (unsigned char*) "TRUE") == 0)
00234 {
00235 LM_DBG("found content true\n");
00236 xmlFree(content);
00237 continue;
00238 }
00239 xmlFree(content);
00240 }
00241
00242 while (doc_node )
00243 {
00244 if (xmlStrcasecmp(doc_node->name,(unsigned char*)"text")==0)
00245 {
00246 doc_node = doc_node->next;
00247 continue;
00248 }
00249
00250 if (xmlStrcasecmp(doc_node->name,(unsigned char*)name)!=0)
00251 {
00252 break;
00253 }
00254 all_node = xmlNodeGetChildByName(node, all_name) ;
00255
00256 if( all_node )
00257 {
00258 LM_DBG("must provide all\n");
00259 doc_node = doc_node->next;
00260 continue;
00261 }
00262
00263 found = 0;
00264 class_cont = xmlNodeGetNodeContentByName(doc_node, "class",
00265 NULL);
00266 if(class_cont == NULL)
00267 LM_DBG("no class tag found\n");
00268 else
00269 LM_DBG("found class = %s\n", class_cont);
00270
00271 occurence_ID = xmlNodeGetAttrContentByName(doc_node, "id");
00272 if(occurence_ID == NULL)
00273 LM_DBG("no id found\n");
00274 else
00275 LM_DBG("found id = %s\n", occurence_ID);
00276
00277
00278 deviceID = xmlNodeGetNodeContentByName(doc_node, "deviceID",
00279 NULL);
00280 if(deviceID== NULL)
00281 LM_DBG("no deviceID found\n");
00282 else
00283 LM_DBG("found deviceID = %s\n", deviceID);
00284
00285
00286 service_uri = xmlNodeGetNodeContentByName(doc_node, "contact",
00287 NULL);
00288 if(service_uri == NULL)
00289 LM_DBG("no service_uri found\n");
00290 else
00291 LM_DBG("found service_uri = %s\n", service_uri);
00292 i = 0;
00293 if(service_uri!= NULL)
00294 {
00295 while(service_uri[i]!= ':')
00296 {
00297 service_uri_scheme[i] = service_uri[i];
00298 i++;
00299 }
00300 service_uri_scheme[i] = '\0';
00301 LM_DBG("service_uri_scheme: %s\n", service_uri_scheme);
00302 }
00303
00304 provide_node = node->children;
00305
00306 while ( provide_node!= NULL )
00307 {
00308 if(xmlStrcasecmp(provide_node->name,(unsigned char*) "text")==0)
00309 {
00310 provide_node = provide_node->next;
00311 continue;
00312 }
00313
00314 if(xmlStrcasecmp(provide_node->name,(unsigned char*)"class")== 0
00315 && class_cont )
00316 {
00317 content = (char*)xmlNodeGetContent(provide_node);
00318
00319 if(content&& xmlStrcasecmp((unsigned char*)content,
00320 (unsigned char*)class_cont) == 0)
00321 {
00322 found = 1;
00323 LM_DBG("found class= %s", class_cont);
00324 xmlFree(content);
00325 break;
00326 }
00327 if(content)
00328 xmlFree(content);
00329 }
00330 if(xmlStrcasecmp(provide_node->name,
00331 (unsigned char*) "deviceID")==0&&deviceID )
00332 {
00333 content = (char*)xmlNodeGetContent(provide_node);
00334
00335 if(content && xmlStrcasecmp ((unsigned char*)content,
00336 (unsigned char*)deviceID) == 0)
00337 {
00338 found = 1;
00339 LM_DBG("found deviceID= %s", deviceID);
00340 xmlFree(content);
00341 break;
00342 }
00343 if(content)
00344 xmlFree(content);
00345
00346 }
00347 if(xmlStrcasecmp(provide_node->name,
00348 (unsigned char*)"occurence-id")== 0&& occurence_ID)
00349 {
00350 content = (char*)xmlNodeGetContent(provide_node);
00351 if(content && xmlStrcasecmp ((unsigned char*)content,
00352 (unsigned char*)occurence_ID) == 0)
00353 {
00354 found = 1;
00355 LM_DBG("found occurenceID= %s\n", occurence_ID);
00356 xmlFree(content);
00357 break;
00358 }
00359 if(content)
00360 xmlFree(content);
00361
00362 }
00363 if(xmlStrcasecmp(provide_node->name,
00364 (unsigned char*)"service-uri")== 0 && service_uri)
00365 {
00366 content = (char*)xmlNodeGetContent(provide_node);
00367 if(content&& xmlStrcasecmp ((unsigned char*)content,
00368 (unsigned char*)service_uri) == 0)
00369 {
00370 found = 1;
00371 LM_DBG("found service_uri= %s", service_uri);
00372 xmlFree(content);
00373 break;
00374 }
00375 if(content)
00376 xmlFree(content);
00377
00378 }
00379
00380 if(xmlStrcasecmp(provide_node->name,
00381 (unsigned char*)"service-uri-scheme")==0&& i)
00382 {
00383 content = (char*)xmlNodeGetContent(provide_node);
00384 LM_DBG("service_uri_scheme=%s\n",content);
00385 if(content && xmlStrcasecmp((unsigned char*)content,
00386 (unsigned char*)service_uri_scheme) == 0)
00387 {
00388 found = 1;
00389 LM_DBG("found service_uri_scheme= %s", service_uri_scheme);
00390 xmlFree(content);
00391 break;
00392 }
00393 if(content)
00394 xmlFree(content);
00395
00396 }
00397
00398 provide_node = provide_node->next;
00399 }
00400
00401 if(found == 0)
00402 {
00403 LM_DBG("delete node: %s\n", doc_node->name);
00404 dont_provide = doc_node;
00405 doc_node = doc_node->next;
00406 xmlUnlinkNode(dont_provide);
00407 xmlFreeNode(dont_provide);
00408 }
00409 else
00410 doc_node = doc_node->next;
00411
00412 }
00413 }
00414
00415 done:
00416 xmlDocDumpFormatMemory(doc,(xmlChar**)(void*)&new_body->s,
00417 &new_body->len, 1);
00418 LM_DBG("body = \n%.*s\n", new_body->len,
00419 new_body->s);
00420
00421 xmlFreeDoc(doc);
00422
00423 xmlFree(class_cont);
00424 xmlFree(occurence_ID);
00425 xmlFree(deviceID);
00426 xmlFree(service_uri);
00427 xmlCleanupParser();
00428 xmlMemoryDump();
00429
00430 return new_body;
00431 error:
00432 if(doc)
00433 xmlFreeDoc(doc);
00434 if(new_body)
00435 {
00436 if(new_body->s)
00437 xmlFree(new_body->s);
00438 pkg_free(new_body);
00439 }
00440 if(class_cont)
00441 xmlFree(class_cont);
00442 if(occurence_ID)
00443 xmlFree(occurence_ID);
00444 if(deviceID)
00445 xmlFree(deviceID);
00446 if(service_uri)
00447 xmlFree(service_uri);
00448
00449 return NULL;
00450 }
00451
00452 str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n)
00453 {
00454 int i, j= 0, append ;
00455 xmlNodePtr p_root= NULL, new_p_root= NULL ;
00456 xmlDocPtr* xml_array ;
00457 xmlNodePtr node = NULL;
00458 xmlNodePtr add_node = NULL ;
00459 str *body= NULL;
00460 char* id= NULL, *tuple_id = NULL;
00461 xmlDocPtr pidf_manip_doc= NULL;
00462 str* pidf_doc= NULL;
00463
00464 xml_array = (xmlDocPtr*)pkg_malloc( (n+2)*sizeof(xmlDocPtr));
00465 if(xml_array== NULL)
00466 {
00467
00468 LM_ERR("while alocating memory");
00469 return NULL;
00470 }
00471 memset(xml_array, 0, (n+2)*sizeof(xmlDocPtr)) ;
00472
00473
00474 if(pidf_manipulation)
00475 {
00476 if( get_rules_doc(pres_user, pres_domain, PIDF_MANIPULATION, &pidf_doc)< 0)
00477 {
00478 LM_ERR("while getting xcap tree for doc_type PIDF_MANIPULATION\n");
00479 goto error;
00480 }
00481 if(pidf_doc== NULL)
00482 {
00483 LM_DBG("No PIDF_MANIPULATION doc for [user]= %.*s [domain]= %.*s\n"
00484 ,pres_user->len, pres_user->s, pres_domain->len, pres_domain->s);
00485 }
00486 else
00487 {
00488 pidf_manip_doc= xmlParseMemory(pidf_doc->s, pidf_doc->len);
00489 pkg_free(pidf_doc->s);
00490 pkg_free(pidf_doc);
00491
00492 if(pidf_manip_doc== NULL)
00493 {
00494 LM_ERR("parsing xml memory\n");
00495 goto error;
00496 }
00497 else
00498 {
00499 xml_array[0]= pidf_manip_doc;
00500 j++;
00501 }
00502 }
00503 }
00504
00505 for(i=0; i<n; i++)
00506 {
00507 if(body_array[i] == NULL )
00508 continue;
00509
00510 xml_array[j] = NULL;
00511 xml_array[j] = xmlParseMemory( body_array[i]->s, body_array[i]->len );
00512
00513 if( xml_array[j]== NULL)
00514 {
00515 LM_ERR("while parsing xml body message\n");
00516 goto error;
00517 }
00518 j++;
00519
00520 }
00521
00522 if(j== 0)
00523 {
00524 if(xml_array)
00525 pkg_free(xml_array);
00526 return NULL;
00527 }
00528
00529 j--;
00530 p_root = xmlDocGetNodeByName( xml_array[j], "presence", NULL);
00531 if(p_root ==NULL)
00532 {
00533 LM_ERR("while geting the xml_tree root\n");
00534 goto error;
00535 }
00536
00537 for(i= j-1; i>=0; i--)
00538 {
00539 new_p_root= xmlDocGetNodeByName( xml_array[i], "presence", NULL);
00540 if(new_p_root ==NULL)
00541 {
00542 LM_ERR("while geting the xml_tree root\n");
00543 goto error;
00544 }
00545
00546 append= 1;
00547 node= xmlNodeGetChildByName(new_p_root, "tuple");
00548 if(node != NULL)
00549 {
00550 tuple_id= xmlNodeGetAttrContentByName(node, "id");
00551 if(tuple_id== NULL)
00552 {
00553 LM_ERR("while extracting tuple id\n");
00554 goto error;
00555 }
00556 for (node = p_root->children; node!=NULL; node = node->next)
00557 {
00558 if( xmlStrcasecmp(node->name,(unsigned char*)"text")==0)
00559 continue;
00560
00561 if( xmlStrcasecmp(node->name,(unsigned char*)"tuple")==0)
00562 {
00563 id = xmlNodeGetAttrContentByName(node, "id");
00564 if(id== NULL)
00565 {
00566 LM_ERR("while extracting tuple id\n");
00567 goto error;
00568 }
00569
00570 if(xmlStrcasecmp((unsigned char*)tuple_id,
00571 (unsigned char*)id )== 0)
00572 {
00573 append = 0;
00574 xmlFree(id);
00575 break;
00576 }
00577 xmlFree(id);
00578 }
00579 }
00580 xmlFree(tuple_id);
00581 tuple_id= NULL;
00582 }
00583
00584 if(append)
00585 {
00586 for(node= new_p_root->children; node; node= node->next)
00587 {
00588 add_node= xmlCopyNode(node, 1);
00589 if(add_node== NULL)
00590 {
00591 LM_ERR("while copying node\n");
00592 goto error;
00593 }
00594 if(xmlAddChild(p_root, add_node)== NULL)
00595 {
00596 LM_ERR("while adding child\n");
00597 goto error;
00598 }
00599
00600 }
00601 }
00602 }
00603
00604 body = (str*)pkg_malloc(sizeof(str));
00605 if(body == NULL)
00606 {
00607 ERR_MEM(PKG_MEM_STR);
00608 }
00609
00610 xmlDocDumpFormatMemory(xml_array[j],(xmlChar**)(void*)&body->s,
00611 &body->len, 1);
00612
00613 for(i=0; i<=j; i++)
00614 {
00615 if(xml_array[i]!=NULL)
00616 xmlFreeDoc( xml_array[i]);
00617 }
00618 if(xml_array!=NULL)
00619 pkg_free(xml_array);
00620
00621 xmlCleanupParser();
00622 xmlMemoryDump();
00623
00624 return body;
00625
00626 error:
00627 if(xml_array!=NULL)
00628 {
00629 for(i=0; i<=j; i++)
00630 {
00631 if(xml_array[i]!=NULL)
00632 xmlFreeDoc( xml_array[i]);
00633 }
00634 pkg_free(xml_array);
00635 }
00636 if(tuple_id)
00637 xmlFree(tuple_id);
00638 if(body)
00639 pkg_free(body);
00640
00641 return NULL;
00642 }
00643
00644 str* offline_nbody(str* body)
00645 {
00646 xmlDocPtr doc= NULL;
00647 xmlDocPtr new_doc= NULL;
00648 xmlNodePtr node, tuple_node= NULL, status_node;
00649 xmlNodePtr root_node, add_node, pres_node;
00650 str* new_body;
00651
00652 doc= xmlParseMemory(body->s, body->len);
00653 if(doc== NULL)
00654 {
00655 LM_ERR("while parsing xml memory\n");
00656 return NULL;
00657 }
00658 node= xmlDocGetNodeByName(doc, "basic", NULL);
00659 if(node== NULL)
00660 {
00661 LM_ERR("while extracting basic node\n");
00662 goto error;
00663 }
00664 xmlNodeSetContent(node, (const unsigned char*)"closed");
00665
00666 tuple_node= xmlDocGetNodeByName(doc, "tuple", NULL);
00667 if(tuple_node== NULL)
00668 {
00669 LM_ERR("while extracting tuple node\n");
00670 goto error;
00671 }
00672 status_node= xmlDocGetNodeByName(doc, "status", NULL);
00673 if(status_node== NULL)
00674 {
00675 LM_ERR("while extracting tuple node\n");
00676 goto error;
00677 }
00678
00679 pres_node= xmlDocGetNodeByName(doc, "presence", NULL);
00680 if(node== NULL)
00681 {
00682 LM_ERR("while extracting presence node\n");
00683 goto error;
00684 }
00685
00686 new_doc = xmlNewDoc(BAD_CAST "1.0");
00687 if(new_doc==0)
00688 goto error;
00689 root_node= xmlCopyNode(pres_node, 2);
00690 if(root_node== NULL)
00691 {
00692 LM_ERR("while copying node\n");
00693 goto error;
00694 }
00695 xmlDocSetRootElement(new_doc, root_node);
00696
00697 tuple_node= xmlCopyNode(tuple_node, 2);
00698 if(tuple_node== NULL)
00699 {
00700 LM_ERR("while copying node\n");
00701 goto error;
00702 }
00703 xmlAddChild(root_node, tuple_node);
00704
00705 add_node= xmlCopyNode(status_node, 1);
00706 if(add_node== NULL)
00707 {
00708 LM_ERR("while copying node\n");
00709 goto error;
00710 }
00711 xmlAddChild(tuple_node, add_node);
00712
00713 new_body = (str*)pkg_malloc(sizeof(str));
00714 if(new_body == NULL)
00715 {
00716 ERR_MEM(PKG_MEM_STR);
00717 }
00718 memset(new_body, 0, sizeof(str));
00719
00720 xmlDocDumpFormatMemory(new_doc,(xmlChar**)(void*)&new_body->s,
00721 &new_body->len, 1);
00722
00723 xmlFreeDoc(doc);
00724 xmlFreeDoc(new_doc);
00725 xmlCleanupParser();
00726 xmlMemoryDump();
00727
00728 return new_body;
00729
00730 error:
00731 if(doc)
00732 xmlFreeDoc(doc);
00733 if(new_doc)
00734 xmlFreeDoc(new_doc);
00735 return NULL;
00736
00737 }
00738