mirror of https://github.com/sipwise/kamailio.git
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.
224 lines
4.2 KiB
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;
|
|
}
|
|
|