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
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <time.h>
00039 #include <libxml/parser.h>
00040
00041 #include "../../str.h"
00042 #include "../../dprint.h"
00043 #include "../../parser/parse_uri.h"
00044 #include "../presence/utils_func.h"
00045 #include "../presence/hash.h"
00046 #include "presence_xml.h"
00047 #include "xcap_auth.h"
00048 #include "pidf.h"
00049
00050 int http_get_rules_doc(str user, str domain, str* rules_doc);
00051
00052 int pres_watcher_allowed(subs_t* subs)
00053 {
00054 xmlDocPtr xcap_tree= NULL;
00055 xmlNodePtr node= NULL, actions_node = NULL;
00056 xmlNodePtr sub_handling_node = NULL;
00057 char* sub_handling = NULL;
00058
00059
00060 if(force_active)
00061 {
00062 subs->status= ACTIVE_STATUS;
00063 subs->reason.s= NULL;
00064 subs->reason.len= 0;
00065 return 0;
00066 }
00067 subs->status= PENDING_STATUS;
00068 subs->reason.s= NULL;
00069 subs->reason.len= 0;
00070
00071 if(subs->auth_rules_doc== NULL)
00072 {
00073 return 0;
00074 }
00075
00076 xcap_tree= xmlParseMemory(subs->auth_rules_doc->s,
00077 subs->auth_rules_doc->len);
00078 if(xcap_tree== NULL)
00079 {
00080 LM_ERR("parsing xml memory\n");
00081 return -1;
00082 }
00083
00084 node= get_rule_node(subs, xcap_tree);
00085 if(node== NULL)
00086 {
00087 xmlFreeDoc(xcap_tree);
00088 return 0;
00089 }
00090
00091
00092 actions_node = xmlNodeGetChildByName(node, "actions");
00093 if(actions_node == NULL)
00094 {
00095 LM_DBG("actions_node NULL\n");
00096 xmlFreeDoc(xcap_tree);
00097 return 0;
00098 }
00099 LM_DBG("actions_node->name= %s\n",
00100 actions_node->name);
00101
00102 sub_handling_node = xmlNodeGetChildByName(actions_node, "sub-handling");
00103 if(sub_handling_node== NULL)
00104 {
00105 LM_DBG("sub_handling_node NULL\n");
00106 xmlFreeDoc(xcap_tree);
00107 return 0;
00108 }
00109 sub_handling = (char*)xmlNodeGetContent(sub_handling_node);
00110 LM_DBG("sub_handling_node->name= %s\n",
00111 sub_handling_node->name);
00112 LM_DBG("sub_handling_node->content= %s\n",
00113 sub_handling);
00114
00115 if(sub_handling== NULL)
00116 {
00117 LM_ERR("Couldn't get sub-handling content\n");
00118 xmlFreeDoc(xcap_tree);
00119 return -1;
00120 }
00121 if( strncmp((char*)sub_handling, "block",5 )==0)
00122 {
00123 subs->status = TERMINATED_STATUS;;
00124 subs->reason.s= "rejected";
00125 subs->reason.len = 8;
00126 }
00127 else
00128 if( strncmp((char*)sub_handling, "confirm",7 )==0)
00129 {
00130 subs->status = PENDING_STATUS;
00131 }
00132 else
00133 if( strncmp((char*)sub_handling , "polite-block",12 )==0)
00134 {
00135 subs->status = ACTIVE_STATUS;
00136 subs->reason.s= "polite-block";
00137 subs->reason.len = 12;
00138 }
00139 else
00140 if( strncmp((char*)sub_handling , "allow",5 )==0)
00141 {
00142 subs->status = ACTIVE_STATUS;
00143 subs->reason.s = NULL;
00144 }
00145 else
00146 {
00147 LM_ERR("unknown subscription handling action\n");
00148 xmlFree(sub_handling);
00149 xmlFreeDoc(xcap_tree);
00150 return -1;
00151 }
00152
00153 xmlFree(sub_handling);
00154 xmlFreeDoc(xcap_tree);
00155 return 0;
00156
00157 }
00158
00159 xmlNodePtr get_rule_node(subs_t* subs, xmlDocPtr xcap_tree )
00160 {
00161 str w_uri= {0, 0};
00162 char* id = NULL, *domain = NULL, *time_cont= NULL;
00163 int apply_rule = -1;
00164 xmlNodePtr ruleset_node = NULL, node1= NULL, node2= NULL;
00165 xmlNodePtr cond_node = NULL, except_node = NULL;
00166 xmlNodePtr identity_node = NULL, sphere_node = NULL;
00167 xmlNodePtr iden_child;
00168 xmlNodePtr validity_node, time_node;
00169 time_t t_init, t_fin, t;
00170 int valid= 0;
00171
00172
00173 uandd_to_uri(subs->watcher_user, subs->watcher_domain, &w_uri);
00174 if(w_uri.s == NULL)
00175 {
00176 LM_ERR("while creating uri\n");
00177 return NULL;
00178 }
00179 ruleset_node = xmlDocGetNodeByName(xcap_tree, "ruleset", NULL);
00180 if(ruleset_node == NULL)
00181 {
00182 LM_DBG("ruleset_node NULL\n");
00183 goto error;
00184
00185 }
00186 for(node1 = ruleset_node->children ; node1; node1 = node1->next)
00187 {
00188 if(xmlStrcasecmp(node1->name, (unsigned char*)"text")==0 )
00189 continue;
00190
00191
00192 LM_DBG("node1->name= %s\n", node1->name);
00193
00194 cond_node = xmlNodeGetChildByName(node1, "conditions");
00195 if(cond_node == NULL)
00196 {
00197 LM_DBG("cond node NULL\n");
00198 goto error;
00199 }
00200 LM_DBG("cond_node->name= %s\n", cond_node->name);
00201
00202 validity_node = xmlNodeGetChildByName(cond_node, "validity");
00203 if(validity_node !=NULL)
00204 {
00205 LM_DBG("found validity tag\n");
00206
00207 t= time(NULL);
00208
00209
00210 for(time_node= validity_node->children; time_node;
00211 time_node= time_node->next)
00212 {
00213 if(xmlStrcasecmp(time_node->name, (unsigned char*)"from")!= 0)
00214 {
00215 continue;
00216 }
00217 time_cont= (char*)xmlNodeGetContent(time_node);
00218 t_init= xml_parse_dateTime(time_cont);
00219 xmlFree(time_cont);
00220 if(t_init< 0)
00221 {
00222 LM_ERR("failed to parse xml dateTime\n");
00223 goto error;
00224 }
00225
00226 if(t< t_init)
00227 {
00228 LM_DBG("the lower time limit is not respected\n");
00229 continue;
00230 }
00231
00232 time_node= time_node->next;
00233 while(1)
00234 {
00235 if(time_node== NULL)
00236 {
00237 LM_ERR("bad formatted xml doc:until child not found in"
00238 " validity pair\n");
00239 goto error;
00240 }
00241 if( xmlStrcasecmp(time_node->name,
00242 (unsigned char*)"until")== 0)
00243 break;
00244 time_node= time_node->next;
00245 }
00246
00247 time_cont= (char*)xmlNodeGetContent(time_node);
00248 t_fin= xml_parse_dateTime(time_cont);
00249 xmlFree(time_cont);
00250
00251 if(t_fin< 0)
00252 {
00253 LM_ERR("failed to parse xml dateTime\n");
00254 goto error;
00255 }
00256
00257 if(t <= t_fin)
00258 {
00259 LM_DBG("the rule is active at this time\n");
00260 valid= 1;
00261 }
00262
00263 }
00264
00265 if(!valid)
00266 {
00267 LM_DBG("the rule is not active at this time\n");
00268 continue;
00269 }
00270
00271 }
00272
00273 sphere_node = xmlNodeGetChildByName(cond_node, "sphere");
00274 if(sphere_node!= NULL)
00275 {
00276
00277
00278
00279 char* sphere= pres_get_sphere(&subs->pres_uri);
00280 if(sphere)
00281 {
00282 char* attr= (char*)xmlNodeGetContent(sphere_node);
00283 if(xmlStrcasecmp((unsigned char*)attr, (unsigned char*)sphere)!= 0)
00284 {
00285 LM_DBG("sphere condition not respected\n");
00286 pkg_free(sphere);
00287 xmlFree(attr);
00288 continue;
00289 }
00290 pkg_free(sphere);
00291 xmlFree(attr);
00292
00293 }
00294
00295
00296
00297 }
00298
00299 identity_node = xmlNodeGetChildByName(cond_node, "identity");
00300 if(identity_node == NULL)
00301 {
00302 LM_ERR("didn't find identity tag\n");
00303 goto error;
00304 }
00305
00306 iden_child= xmlNodeGetChildByName(identity_node, "one");
00307 if(iden_child)
00308 {
00309 for(node2 = identity_node->children; node2; node2 = node2->next)
00310 {
00311 if(xmlStrcasecmp(node2->name, (unsigned char*)"one")!= 0)
00312 continue;
00313
00314 id = xmlNodeGetAttrContentByName(node2, "id");
00315 if(id== NULL)
00316 {
00317 LM_ERR("while extracting attribute\n");
00318 goto error;
00319 }
00320 if((strlen(id)== w_uri.len &&
00321 (strncmp(id, w_uri.s, w_uri.len)==0)))
00322 {
00323 apply_rule = 1;
00324 xmlFree(id);
00325 break;
00326 }
00327 xmlFree(id);
00328 }
00329 }
00330
00331
00332 iden_child= xmlNodeGetChildByName(identity_node, "many");
00333 if(iden_child)
00334 {
00335 domain = NULL;
00336 for(node2 = identity_node->children; node2; node2 = node2->next)
00337 {
00338 if(xmlStrcasecmp(node2->name, (unsigned char*)"many")!= 0)
00339 continue;
00340
00341 domain = xmlNodeGetAttrContentByName(node2, "domain");
00342 if(domain == NULL)
00343 {
00344 LM_DBG("No domain attribute to many\n");
00345 }
00346 else
00347 {
00348 LM_DBG("<many domain= %s>\n", domain);
00349 if((strlen(domain)!= subs->from_domain.len &&
00350 strncmp(domain, subs->from_domain.s,
00351 subs->from_domain.len) ))
00352 {
00353 xmlFree(domain);
00354 continue;
00355 }
00356 }
00357 xmlFree(domain);
00358 apply_rule = 1;
00359 if(node2->children == NULL)
00360 break;
00361
00362 for(except_node = node2->children; except_node;
00363 except_node= except_node->next)
00364 {
00365 if(xmlStrcasecmp(except_node->name, (unsigned char*)"except"))
00366 continue;
00367
00368 id = xmlNodeGetAttrContentByName(except_node, "id");
00369 if(id!=NULL)
00370 {
00371 if((strlen(id)- 1== w_uri.len &&
00372 (strncmp(id, w_uri.s, w_uri.len)==0)))
00373 {
00374 xmlFree(id);
00375 apply_rule = 0;
00376 break;
00377 }
00378 xmlFree(id);
00379 }
00380 else
00381 {
00382 domain = NULL;
00383 domain = xmlNodeGetAttrContentByName(except_node, "domain");
00384 if(domain!=NULL)
00385 {
00386 LM_DBG("Found except domain= %s\n- strlen(domain)= %d\n",
00387 domain, (int)strlen(domain));
00388 if(strlen(domain)==subs->from_domain.len &&
00389 (strncmp(domain,subs->from_domain.s , subs->from_domain.len)==0))
00390 {
00391 LM_DBG("except domain match\n");
00392 xmlFree(domain);
00393 apply_rule = 0;
00394 break;
00395 }
00396 xmlFree(domain);
00397 }
00398
00399 }
00400 }
00401 if(apply_rule== 1)
00402 break;
00403
00404 }
00405 }
00406 if(apply_rule ==1)
00407 break;
00408 }
00409
00410 LM_DBG("apply_rule= %d\n", apply_rule);
00411 if(w_uri.s!=NULL)
00412 pkg_free(w_uri.s);
00413
00414 if( !apply_rule || !node1)
00415 return NULL;
00416
00417 return node1;
00418
00419 error:
00420 if(w_uri.s)
00421 pkg_free(w_uri.s);
00422 return NULL;
00423 }
00424
00425 int pres_get_rules_doc(str* user, str* domain, str** rules_doc)
00426 {
00427
00428 return get_rules_doc(user, domain, PRES_RULES, rules_doc);
00429 }
00430
00431 int get_rules_doc(str* user, str* domain, int type, str** rules_doc)
00432 {
00433 db_key_t query_cols[5];
00434 db_val_t query_vals[5];
00435 db_key_t result_cols[3];
00436 int n_query_cols = 0;
00437 db1_res_t *result = 0;
00438 db_row_t *row;
00439 db_val_t *row_vals;
00440 str body;
00441 str* doc= NULL;
00442 int n_result_cols= 0, xcap_doc_col;
00443 static str tmp1 = str_init("username");
00444 static str tmp2 = str_init("domain");
00445 static str tmp3 = str_init("doc_type");
00446 static str tmp4 = str_init("doc");
00447
00448 if(force_active)
00449 {
00450 *rules_doc= NULL;
00451 return 0;
00452 }
00453 LM_DBG("[user]= %.*s\t[domain]= %.*s",
00454 user->len, user->s, domain->len, domain->s);
00455
00456 query_cols[n_query_cols] = &tmp1;
00457 query_vals[n_query_cols].type = DB1_STR;
00458 query_vals[n_query_cols].nul = 0;
00459 query_vals[n_query_cols].val.str_val = *user;
00460 n_query_cols++;
00461
00462 query_cols[n_query_cols] = &tmp2;
00463 query_vals[n_query_cols].type = DB1_STR;
00464 query_vals[n_query_cols].nul = 0;
00465 query_vals[n_query_cols].val.str_val = *domain;
00466 n_query_cols++;
00467
00468 query_cols[n_query_cols] = &tmp3;
00469 query_vals[n_query_cols].type = DB1_INT;
00470 query_vals[n_query_cols].nul = 0;
00471 query_vals[n_query_cols].val.int_val= type;
00472 n_query_cols++;
00473
00474 result_cols[xcap_doc_col= n_result_cols++] = &tmp4;
00475
00476 if (pxml_dbf.use_table(pxml_db, &xcap_table) < 0)
00477 {
00478 LM_ERR("in use_table-[table]= %.*s\n", xcap_table.len, xcap_table.s);
00479 return -1;
00480 }
00481
00482 if( pxml_dbf.query(pxml_db, query_cols, 0 , query_vals, result_cols,
00483 n_query_cols, 1, 0, &result)<0)
00484 {
00485 LM_ERR("while querying table xcap for [user]=%.*s\t[domain]= %.*s\n",
00486 user->len, user->s, domain->len, domain->s);
00487 if(result)
00488 pxml_dbf.free_result(pxml_db, result);
00489 return -1;
00490 }
00491 if(result== NULL)
00492 return -1;
00493
00494 if(result->n<= 0)
00495 {
00496 LM_DBG("No document found in db table for [user]=%.*s"
00497 "\t[domain]= %.*s\t[doc_type]= %d\n",user->len, user->s,
00498 domain->len, domain->s, type);
00499
00500 if(!integrated_xcap_server)
00501 {
00502 if(http_get_rules_doc(*user, *domain, &body)< 0)
00503 {
00504 LM_ERR("sending http GET request to xcap server\n");
00505 goto error;
00506 }
00507 if(body.s && body.len)
00508 goto done;
00509 }
00510 pxml_dbf.free_result(pxml_db, result);
00511 return 0;
00512 }
00513
00514 row = &result->rows[xcap_doc_col];
00515 row_vals = ROW_VALUES(row);
00516
00517 body.s = (char*)row_vals[0].val.string_val;
00518 if(body.s== NULL)
00519 {
00520 LM_ERR("Xcap doc NULL\n");
00521 goto error;
00522 }
00523 body.len = strlen(body.s);
00524 if(body.len== 0)
00525 {
00526 LM_ERR("Xcap doc empty\n");
00527 goto error;
00528 }
00529 LM_DBG("xcap document:\n%.*s", body.len,body.s);
00530
00531 done:
00532 doc= (str*)pkg_malloc(sizeof(str));
00533 if(doc== NULL)
00534 {
00535 ERR_MEM(PKG_MEM_STR);
00536 }
00537 doc->s= (char*)pkg_malloc(body.len* sizeof(char));
00538 if(doc->s== NULL)
00539 {
00540 pkg_free(doc);
00541 ERR_MEM(PKG_MEM_STR);
00542 }
00543 memcpy(doc->s, body.s, body.len);
00544 doc->len= body.len;
00545
00546 *rules_doc= doc;
00547
00548 if(result)
00549 pxml_dbf.free_result(pxml_db, result);
00550
00551 return 0;
00552
00553 error:
00554 if(result)
00555 pxml_dbf.free_result(pxml_db, result);
00556
00557 return -1;
00558
00559 }
00560
00561 int http_get_rules_doc(str user, str domain, str* rules_doc)
00562 {
00563 str uri;
00564 xcap_doc_sel_t doc_sel;
00565 char* doc= NULL;
00566 xcap_serv_t* xs;
00567 xcap_get_req_t req;
00568
00569 memset(&req, 0, sizeof(xcap_get_req_t));
00570 if(uandd_to_uri(user, domain, &uri)< 0)
00571 {
00572 LM_ERR("constructing uri\n");
00573 goto error;
00574 }
00575
00576 doc_sel.auid.s= "pres-rules";
00577 doc_sel.auid.len= strlen("pres-rules");
00578 doc_sel.doc_type= PRES_RULES;
00579 doc_sel.type= USERS_TYPE;
00580 doc_sel.xid= uri;
00581 doc_sel.filename.s= "index";
00582 doc_sel.filename.len= 5;
00583
00584
00585
00586
00587 req.doc_sel= doc_sel;
00588
00589 xs= xs_list;
00590 while(xs)
00591 {
00592 req.xcap_root= xs->addr;
00593 req.port= xs->port;
00594 doc= xcap_GetNewDoc(req, user, domain);
00595 if(doc!=NULL)
00596 break;
00597 xs = xs->next;
00598 }
00599
00600 rules_doc->s= doc;
00601 rules_doc->len= doc?strlen(doc):0;
00602
00603 return 0;
00604
00605 error:
00606 return -1;
00607 }