Skip to content

Commit

Permalink
permissions: match trusted rules considering priority and regexp over…
Browse files Browse the repository at this point in the history
… r-uri

- two new columns to set priority of the rule as well as regular
  expression matching over r-uri
  • Loading branch information
Emmanuel Schmidbauer authored and miconda committed Jun 17, 2015
1 parent 8124362 commit 4f635fa
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 43 deletions.
98 changes: 81 additions & 17 deletions modules/permissions/hash.c
Expand Up @@ -22,6 +22,7 @@

#include <sys/types.h>
#include <regex.h>
#include "parse_config.h"
#include "../../mem/shm_mem.h"
#include "../../parser/parse_from.h"
#include "../../ut.h"
Expand Down Expand Up @@ -116,13 +117,15 @@ void free_hash_table(struct trusted_list** table)


/*
* Add <src_ip, proto, pattern, tag> into hash table, where proto is integer
* Add <src_ip, proto, pattern, ruri_pattern, tag, priority> into hash table, where proto is integer
* representation of string argument proto.
*/
int hash_table_insert(struct trusted_list** table, char* src_ip,
char* proto, char* pattern, char* tag)
char* proto, char* pattern, char* ruri_pattern, char* tag, int priority)
{
struct trusted_list *np;
struct trusted_list *np0 = NULL;
struct trusted_list *np1 = NULL;
unsigned int hash_val;

np = (struct trusted_list *) shm_malloc(sizeof(*np));
Expand Down Expand Up @@ -179,13 +182,27 @@ int hash_table_insert(struct trusted_list** table, char* src_ip,
np->pattern = 0;
}

if (ruri_pattern) {
np->ruri_pattern = (char *) shm_malloc(strlen(ruri_pattern)+1);
if (np->ruri_pattern == NULL) {
LM_CRIT("cannot allocate shm memory for ruri_pattern string\n");
shm_free(np->src_ip.s);
shm_free(np);
return -1;
}
(void) strcpy(np->ruri_pattern, ruri_pattern);
} else {
np->ruri_pattern = 0;
}

if (tag) {
np->tag.len = strlen(tag);
np->tag.s = (char *) shm_malloc((np->tag.len) + 1);
if (np->tag.s == NULL) {
LM_CRIT("cannot allocate shm memory for pattern string\n");
LM_CRIT("cannot allocate shm memory for pattern or ruri_pattern string\n");
shm_free(np->src_ip.s);
shm_free(np->pattern);
shm_free(np->ruri_pattern);
shm_free(np);
return -1;
}
Expand All @@ -195,9 +212,29 @@ int hash_table_insert(struct trusted_list** table, char* src_ip,
np->tag.s = 0;
}

np->priority = priority;

hash_val = perm_hash(np->src_ip);
np->next = table[hash_val];
table[hash_val] = np;
if(table[hash_val]==NULL) {
np->next = NULL;
table[hash_val] = np;
} else {
np1 = NULL;
np0 = table[hash_val];
while(np0) {
if(np0->priority < np->priority)
break;
np1 = np0;
np0 = np0->next;
}
if(np1==NULL) {
np->next = table[hash_val];
table[hash_val] = np;
} else {
np->next = np1->next;
np1->next = np;
}
}

return 1;
}
Expand All @@ -212,8 +249,9 @@ int hash_table_insert(struct trusted_list** table, char* src_ip,
int match_hash_table(struct trusted_list** table, struct sip_msg* msg,
char *src_ip_c_str, int proto)
{
str uri;
str uri, ruri;
char uri_string[MAX_URI_SIZE + 1];
char ruri_string[MAX_URI_SIZE + 1];
regex_t preg;
struct trusted_list *np;
str src_ip;
Expand All @@ -233,23 +271,45 @@ int match_hash_table(struct trusted_list** table, struct sip_msg* msg,
}
memcpy(uri_string, uri.s, uri.len);
uri_string[uri.len] = (char)0;
ruri = msg->first_line.u.request.uri;
if (ruri.len > MAX_URI_SIZE) {
LM_ERR("message has Request URI too large\n");
return -1;
}
memcpy(ruri_string, ruri.s, ruri.len);
ruri_string[ruri.len] = (char)0;
}

for (np = table[perm_hash(src_ip)]; np != NULL; np = np->next) {
if ((np->src_ip.len == src_ip.len) &&
(strncmp(np->src_ip.s, src_ip.s, src_ip.len) == 0) &&
((np->proto == PROTO_NONE) || (proto == PROTO_NONE) ||
(np->proto == proto))) {
if (np->pattern && IS_SIP(msg)) {
if (regcomp(&preg, np->pattern, REG_NOSUB)) {
LM_ERR("invalid regular expression\n");
continue;
if (IS_SIP(msg)) {
if (np->pattern) {
if (regcomp(&preg, np->pattern, REG_NOSUB)) {
LM_ERR("invalid regular expression\n");
if (!np->ruri_pattern) {
continue;
}
}
if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) {
regfree(&preg);
continue;
}
regfree(&preg);
}
if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) {
if (np->ruri_pattern) {
if (regcomp(&preg, np->ruri_pattern, REG_NOSUB)) {
LM_ERR("invalid regular expression\n");
continue;
}
if (regexec(&preg, ruri_string, 0, (regmatch_t *)0, 0)) {
regfree(&preg);
continue;
}
regfree(&preg);
continue;
}
regfree(&preg);
}
/* Found a match */
if (tag_avp.n && np->tag.s) {
Expand Down Expand Up @@ -283,12 +343,14 @@ int hash_table_mi_print(struct trusted_list** table, struct mi_node* rpl)
np = table[i];
while (np) {
if (addf_mi_node_child(rpl, 0, 0, 0,
"%4d <%.*s, %d, %s, %s>",
"%4d <%.*s, %d, %s, %s, %s, %d>",
i,
np->src_ip.len, ZSW(np->src_ip.s),
np->proto,
np->pattern?np->pattern:"NULL",
np->tag.len?np->tag.s:"NULL") == 0) {
np->ruri_pattern?np->ruri_pattern:"NULL",
np->tag.len?np->tag.s:"NULL",
np->priority) == 0) {
return -1;
}
np = np->next;
Expand Down Expand Up @@ -329,9 +391,11 @@ int hash_table_rpc_print(struct trusted_list** hash_table, rpc_t* rpc, void* c)
rpc->fault(c, 500, "Internal error creating rpc data (ip)");
return -1;
}
if(rpc->struct_add(ih, "dss", "proto", np->proto,
if(rpc->struct_add(ih, "dsssd", "proto", np->proto,
"pattern", np->pattern ? np->pattern : "NULL",
"tag", np->tag.len ? np->tag.s : "NULL") < 0)
"ruri_pattern", np->ruri_pattern ? np->ruri_pattern : "NULL",
"tag", np->tag.len ? np->tag.s : "NULL",
"priority", np->priority) < 0)
{
rpc->fault(c, 500, "Internal error creating rpc data");
return -1;
Expand Down
8 changes: 5 additions & 3 deletions modules/permissions/hash.h
Expand Up @@ -41,7 +41,9 @@ struct trusted_list {
str src_ip; /* Source IP of SIP message */
int proto; /* Protocol -- UDP, TCP, TLS, or SCTP */
char *pattern; /* Pattern matching From header field */
char *ruri_pattern; /* Pattern matching Request URI */
str tag; /* Tag to be assigned to AVP */
int priority; /* priority */
struct trusted_list *next; /* Next element in the list */
};

Expand Down Expand Up @@ -77,16 +79,16 @@ void destroy_hash_table(struct trusted_list** table);


/*
* Add <src_ip, proto, pattern> into hash table, where proto is integer
* Add <src_ip, proto, pattern, ruri_pattern, priority> into hash table, where proto is integer
* representation of string argument proto.
*/
int hash_table_insert(struct trusted_list** hash_table, char* src_ip,
char* proto, char* pattern, char* tag);
char* proto, char* pattern, char* ruri_pattern, char* tag, int priority);


/*
* Check if an entry exists in hash table that has given src_ip and protocol
* value and pattern that matches to From URI.
* value and pattern or ruri_pattern that matches to From URI.
*/
int match_hash_table(struct trusted_list** table, struct sip_msg* msg,
char *scr_ip, int proto);
Expand Down
4 changes: 4 additions & 0 deletions modules/permissions/permissions.c
Expand Up @@ -68,7 +68,9 @@ str trusted_table = str_init("trusted"); /* Name of trusted table */
str source_col = str_init("src_ip"); /* Name of source address column */
str proto_col = str_init("proto"); /* Name of protocol column */
str from_col = str_init("from_pattern"); /* Name of from pattern column */
str ruri_col = str_init("ruri_pattern"); /* Name of RURI pattern column */
str tag_col = str_init("tag"); /* Name of tag column */
str priority_col = str_init("priority"); /* Name of priority column */
str tag_avp_param = {NULL, 0}; /* Peer tag AVP spec */
int peer_tag_mode = 0; /* Add tags form all mathcing peers to avp */

Expand Down Expand Up @@ -166,7 +168,9 @@ static param_export_t params[] = {
{"source_col", PARAM_STR, &source_col },
{"proto_col", PARAM_STR, &proto_col },
{"from_col", PARAM_STR, &from_col },
{"ruri_col", PARAM_STR, &ruri_col },
{"tag_col", PARAM_STR, &tag_col },
{"priority_col", PARAM_STR, &priority_col },
{"peer_tag_avp", PARAM_STR, &tag_avp_param },
{"peer_tag_mode", INT_PARAM, &peer_tag_mode },
{"address_table", PARAM_STR, &address_table },
Expand Down
2 changes: 2 additions & 0 deletions modules/permissions/permissions.h
Expand Up @@ -55,7 +55,9 @@ extern str trusted_table; /* Name of trusted table */
extern str source_col; /* Name of source address column */
extern str proto_col; /* Name of protocol column */
extern str from_col; /* Name of from pattern column */
extern str ruri_col; /* Name of RURI pattern column */
extern str tag_col; /* Name of tag column */
extern str priority_col; /* Name of priority column */
extern str address_table; /* Name of address table */
extern str grp_col; /* Name of address group column */
extern str ip_addr_col; /* Name of ip address column */
Expand Down

0 comments on commit 4f635fa

Please sign in to comment.