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