You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kamailio/lib/xcap/common_policy.c

224 lines
4.2 KiB

#include <xcap/common_policy.h>
cp_unknown_t *create_unknown(int data_size)
{
cp_unknown_t *u = cds_malloc(sizeof(cp_unknown_t) + data_size);
u->next = NULL;
return u;
}
/* ------- freeing used memory for common-rules ------- */
static void free_identity(cp_identity_t *id)
{
cp_id_t *i, *ni;
cp_domain_t *d, *nd;
cp_except_t *e, *ne;
cp_except_domain_t *ed, *ned;
if (!id) return;
i = id->ids;
while (i) {
ni = i->next;
str_free_content(&i->entity);
cds_free(i);
i = ni;
}
d = id->domains;
while (d) {
nd = d->next;
str_free_content(&d->domain);
cds_free(d);
d = nd;
}
e = id->excepts;
while (e) {
ne = e->next;
str_free_content(&e->entity);
cds_free(e);
e = ne;
}
if (id->any_identity) {
d = id->any_identity->domains;
while (d) {
nd = d->next;
str_free_content(&d->domain);
cds_free(d);
d = nd;
}
ed = id->any_identity->except_domains;
while (ed) {
ned = ed->next;
str_free_content(&ed->domain);
cds_free(ed);
ed = ned;
}
}
cds_free(id);
}
static void free_conditions(cp_conditions_t *c)
{
cp_sphere_t *s, *n;
if (!c) return;
if (c->validity) cds_free(c->validity);
if (c->identity) free_identity(c->identity);
s = c->spheres;
while (s) {
n = s->next;
str_free_content(&s->value);
cds_free(s);
s = n;
}
cds_free(c);
}
static void free_transformations(cp_transformations_t *t)
{
cp_unknown_t *u, *nu;
if (!t) return;
u = t->unknown;
while (u) {
nu = u->next;
cds_free(u);
u = nu;
}
cds_free(t);
}
void free_cp_rule(cp_rule_t *r, cp_free_actions_func free_actions)
{
if (!r) return;
if (r->conditions) free_conditions(r->conditions);
if (r->actions) free_actions(r->actions);
if (r->transformations) free_transformations(r->transformations);
str_free_content(&r->id);
cds_free(r);
}
void free_common_rules(cp_ruleset_t *r, cp_free_actions_func free_actions)
{
cp_rule_t *rule, *n;
if (!r) return;
rule = r->rules;
while (rule) {
n = rule->next;
free_cp_rule(rule, free_actions);
rule = n;
}
cds_free(r);
}
static void parse_uri(const str_t *uri, str_t *user, str_t *domain)
{
char *a;
char *d;
str_t s;
str_clear(user);
str_clear(domain);
if (uri->len > 0) {
d = str_strchr(uri, ':');
if (d) {
s.s = d + 1;
s.len = uri->len - (s.s - uri->s);
}
else s = *uri;
a = str_strchr(&s, '@');
if (a) {
user->s = s.s;
user->len = a - s.s;
}
domain->s = s.s + user->len;
if (a) domain->s++;
domain->len = uri->len - (domain->s - uri->s);
/* TRACE_LOG("parse uri \'%.*s\': user=\'%.*s\' domain=\'%.*s\'\n",
FMT_STR(*uri), FMT_STR(*user), FMT_STR(*domain));*/
}
}
/* returns 1 if rule is used for uri */
int is_rule_for_uri(cp_rule_t *rule, const str_t *uri)
{
cp_identity_t *id;
int ok = 0;
str_t domain, user;
str_t d_, u_;
cp_domain_t *d;
cp_id_t *i;
cp_except_t *e;
cp_except_domain_t *ed;
if (!rule) return 0;
if (!rule->conditions) return 1; /* FIXME: ??? */
id = rule->conditions->identity;
if (!id) return 0;
parse_uri(uri, &user, &domain);
i = id->ids;
while (i) {
parse_uri(&i->entity, &u_, &d_);
/* TRACE_LOG("comparing uris \'%.*s\' \'%.*s\' "
"domains \'%.*s\' \'%.*s\'\n",
FMT_STR(user), FMT_STR(u_),
FMT_STR(domain), FMT_STR(d_));*/
if (str_case_equals(&user, &u_) == 0) {
if (str_nocase_equals(&domain, &d_) == 0) {
/* TRACE_LOG("id found\n");*/
return 1;
}
}
i = i->next;
}
d = id->domains;
while (d) {
/* TRACE_LOG("comparing domains \'%.*s\' \'%.*s\'\n",
FMT_STR(domain), FMT_STR(d->domain));*/
if (str_nocase_equals(&domain, &d->domain) == 0) ok = 1;
d = d->next;
}
if (ok) {
e = id->excepts;
while (e) {
if (str_case_equals(&user, &e->entity) == 0)
return 0; /* excepts matched */
e = e->next;
}
/* TRACE_LOG("domain found and excepts not matched\n");*/
return 1;
}
if (id->any_identity) {
d = id->any_identity->domains;
while (d) {
if (str_nocase_equals(&domain, &d->domain) == 0) {
/* TRACE_LOG("domain matches for anonymous\n");*/
return 1;
}
d = d->next;
}
ed = id->any_identity->except_domains;
while (ed) {
if (str_nocase_equals(&domain, &d->domain) == 0) return 0;
ed = ed->next;
}
}
return 0;
}