Fixed a bug with regex matching
This commit is contained in:
@ -33,7 +33,7 @@
|
|||||||
*
|
*
|
||||||
* rule2="users John@% Jane@192.168.0.1 match any rules block_salary"
|
* rule2="users John@% Jane@192.168.0.1 match any rules block_salary"
|
||||||
*
|
*
|
||||||
* Rule syntax TODO: query type restrictions
|
* Rule syntax TODO: query type restrictions, update the documentation
|
||||||
*
|
*
|
||||||
* rule NAME deny|allow [wildcard | columns VALUE ... | regex REGEX] [at_times VALUE...]
|
* rule NAME deny|allow [wildcard | columns VALUE ... | regex REGEX] [at_times VALUE...]
|
||||||
*/
|
*/
|
||||||
@ -245,10 +245,10 @@ void* rlistdup(void* fval)
|
|||||||
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
static void* hruledup(void* fval)
|
static void* hruledup(void* fval)
|
||||||
{
|
{
|
||||||
return fval;
|
return fval;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
|
||||||
static void* hrulefree(void* fval)
|
static void* hrulefree(void* fval)
|
||||||
@ -821,80 +821,79 @@ void parse_rule(char* rule, FW_INSTANCE* instance)
|
|||||||
|
|
||||||
|
|
||||||
while(tok){
|
while(tok){
|
||||||
if(strcmp(tok,"wildcard") == 0)
|
if(strcmp(tok,"wildcard") == 0)
|
||||||
{
|
{
|
||||||
ruledef->type = RT_WILDCARD;
|
ruledef->type = RT_WILDCARD;
|
||||||
}
|
}
|
||||||
else if(strcmp(tok,"columns") == 0)
|
else if(strcmp(tok,"columns") == 0)
|
||||||
{
|
{
|
||||||
STRLINK *tail = NULL,*current;
|
STRLINK *tail = NULL,*current;
|
||||||
ruledef->type = RT_COLUMN;
|
ruledef->type = RT_COLUMN;
|
||||||
tok = strtok(NULL, " ,");
|
|
||||||
while(tok && strcmp(tok,"at_times") != 0){
|
|
||||||
current = malloc(sizeof(STRLINK));
|
|
||||||
current->value = strdup(tok);
|
|
||||||
current->next = tail;
|
|
||||||
tail = current;
|
|
||||||
tok = strtok(NULL, " ,");
|
tok = strtok(NULL, " ,");
|
||||||
}
|
while(tok && strcmp(tok,"at_times") != 0){
|
||||||
|
current = malloc(sizeof(STRLINK));
|
||||||
ruledef->data = (void*)tail;
|
current->value = strdup(tok);
|
||||||
continue;
|
current->next = tail;
|
||||||
|
tail = current;
|
||||||
}
|
tok = strtok(NULL, " ,");
|
||||||
else if(strcmp(tok,"at_times") == 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
tok = strtok(NULL, " ,");
|
|
||||||
TIMERANGE *tr = NULL;
|
|
||||||
while(tok){
|
|
||||||
TIMERANGE *tmp = parse_time(tok,instance);
|
|
||||||
|
|
||||||
if(IS_RVRS_TIME(tmp)){
|
|
||||||
tmp = split_reverse_time(tmp);
|
|
||||||
}
|
}
|
||||||
tmp->next = tr;
|
|
||||||
tr = tmp;
|
ruledef->data = (void*)tail;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(strcmp(tok,"at_times") == 0)
|
||||||
|
{
|
||||||
|
|
||||||
tok = strtok(NULL, " ,");
|
tok = strtok(NULL, " ,");
|
||||||
}
|
TIMERANGE *tr = NULL;
|
||||||
ruledef->active = tr;
|
while(tok){
|
||||||
}
|
TIMERANGE *tmp = parse_time(tok,instance);
|
||||||
else if(strcmp(tok,"regex") == 0)
|
|
||||||
{
|
|
||||||
bool escaped = false;
|
|
||||||
tok += 6;
|
|
||||||
|
|
||||||
while(isspace(*tok) || *tok == '\'' || *tok == '"'){
|
if(IS_RVRS_TIME(tmp)){
|
||||||
tok++;
|
tmp = split_reverse_time(tmp);
|
||||||
}
|
}
|
||||||
char* start = tok, *str;
|
tmp->next = tr;
|
||||||
while(true){
|
tr = tmp;
|
||||||
|
tok = strtok(NULL, " ,");
|
||||||
if((*tok == '\'' || *tok == '"') && !escaped){
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
escaped = (*tok == '\\');
|
ruledef->active = tr;
|
||||||
tok++;
|
|
||||||
}
|
}
|
||||||
|
else if(strcmp(tok,"regex") == 0)
|
||||||
|
{
|
||||||
|
bool escaped = false;
|
||||||
|
tok += 6;
|
||||||
|
|
||||||
str = malloc(((tok - start) + 1)*sizeof(char));
|
while(isspace(*tok) || *tok == '\'' || *tok == '"'){
|
||||||
|
tok++;
|
||||||
|
}
|
||||||
|
char* start = tok, *str;
|
||||||
|
while(true){
|
||||||
|
|
||||||
memcpy(str, start, (tok-start));
|
if((*tok == '\'' || *tok == '"') && !escaped){
|
||||||
memset((str + (tok-start) +1),0,1);
|
break;
|
||||||
|
}
|
||||||
|
escaped = (*tok == '\\');
|
||||||
|
tok++;
|
||||||
|
}
|
||||||
|
|
||||||
regex_t *re = malloc(sizeof(regex_t));
|
str = calloc(((tok - start) + 1),sizeof(char));
|
||||||
|
|
||||||
|
memcpy(str, start, (tok-start));
|
||||||
|
|
||||||
|
regex_t *re = malloc(sizeof(regex_t));
|
||||||
|
|
||||||
|
if(regcomp(re, str,REG_NOSUB)){
|
||||||
|
skygw_log_write(LOGFILE_ERROR, "fwfilter: Invalid regular expression '%s'.", str);
|
||||||
|
free(re);
|
||||||
|
}
|
||||||
|
|
||||||
|
ruledef->type = RT_REGEX;
|
||||||
|
ruledef->data = (void*) re;
|
||||||
|
free(str);
|
||||||
|
|
||||||
if(regcomp(re, str,REG_NOSUB)){
|
|
||||||
skygw_log_write(LOGFILE_ERROR, "fwfilter: Invalid regular expression '%s'.", str);
|
|
||||||
free(re);
|
|
||||||
}
|
}
|
||||||
|
tok = strtok(NULL," ,");
|
||||||
ruledef->type = RT_REGEX;
|
|
||||||
ruledef->data = (void*) re;
|
|
||||||
free(str);
|
|
||||||
|
|
||||||
}
|
|
||||||
tok = strtok(NULL," ,");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
goto retblock;
|
goto retblock;
|
||||||
@ -920,7 +919,7 @@ createInstance(char **options, FILTER_PARAMETER **params)
|
|||||||
int i,paramc;
|
int i,paramc;
|
||||||
HASHTABLE* ht;
|
HASHTABLE* ht;
|
||||||
STRLINK *ptr,*tmp;
|
STRLINK *ptr,*tmp;
|
||||||
char *filename, *nl;
|
char *filename = NULL, *nl;
|
||||||
char buffer[2048];
|
char buffer[2048];
|
||||||
FILE* file;
|
FILE* file;
|
||||||
if ((my_instance = calloc(1, sizeof(FW_INSTANCE))) == NULL){
|
if ((my_instance = calloc(1, sizeof(FW_INSTANCE))) == NULL){
|
||||||
@ -939,7 +938,7 @@ createInstance(char **options, FILTER_PARAMETER **params)
|
|||||||
my_instance->def_op = true;
|
my_instance->def_op = true;
|
||||||
|
|
||||||
for(i = 0;params[i];i++){
|
for(i = 0;params[i];i++){
|
||||||
if(strcmp(params[i]->name, "rulelist") == 0){
|
if(strcmp(params[i]->name, "rules") == 0){
|
||||||
filename = strdup(params[i]->value);
|
filename = strdup(params[i]->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1200,29 +1199,29 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue)
|
|||||||
tm_now = localtime(&time_now);
|
tm_now = localtime(&time_now);
|
||||||
|
|
||||||
if((user = (USER*)hashtable_fetch(my_instance->htable, uname_addr)) == NULL){
|
if((user = (USER*)hashtable_fetch(my_instance->htable, uname_addr)) == NULL){
|
||||||
while(user == NULL && next_ip_class(ipaddr)){
|
while(user == NULL && next_ip_class(ipaddr)){
|
||||||
sprintf(uname_addr,"%s@%s",dcb->user,ipaddr);
|
sprintf(uname_addr,"%s@%s",dcb->user,ipaddr);
|
||||||
user = (USER*)hashtable_fetch(my_instance->htable, uname_addr);
|
user = (USER*)hashtable_fetch(my_instance->htable, uname_addr);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(user == NULL){
|
if(user == NULL){
|
||||||
strcpy(ipaddr,dcb->remote);
|
strcpy(ipaddr,dcb->remote);
|
||||||
|
|
||||||
do{
|
do{
|
||||||
sprintf(uname_addr,"%%@%s",ipaddr);
|
sprintf(uname_addr,"%%@%s",ipaddr);
|
||||||
user = (USER*)hashtable_fetch(my_instance->htable, uname_addr);
|
user = (USER*)hashtable_fetch(my_instance->htable, uname_addr);
|
||||||
}while(user == NULL && next_ip_class(ipaddr));
|
}while(user == NULL && next_ip_class(ipaddr));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(user == NULL){
|
if(user == NULL){
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*No rules matched, do default operation.
|
*No rules matched, do default operation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
goto queryresolved;
|
goto queryresolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
is_sql = modutil_is_SQL(queue);
|
is_sql = modutil_is_SQL(queue);
|
||||||
@ -1378,14 +1377,19 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue)
|
|||||||
|
|
||||||
strln = (STRLINK*)rulelist->rule->data;
|
strln = (STRLINK*)rulelist->rule->data;
|
||||||
where = skygw_get_affected_fields(queue);
|
where = skygw_get_affected_fields(queue);
|
||||||
|
rule_match = false;
|
||||||
|
|
||||||
if(where != NULL){
|
if(where != NULL){
|
||||||
|
|
||||||
while(strln){
|
while(strln){
|
||||||
|
|
||||||
|
/**At least one value matched*/
|
||||||
|
|
||||||
if(strstr(where,strln->value)){
|
if(strstr(where,strln->value)){
|
||||||
rule_match = false;
|
rule_match = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
strln = strln->next;
|
strln = strln->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1395,13 +1399,12 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue)
|
|||||||
|
|
||||||
case RT_WILDCARD:
|
case RT_WILDCARD:
|
||||||
|
|
||||||
|
|
||||||
if(is_sql && is_real){
|
if(is_sql && is_real){
|
||||||
|
|
||||||
where = skygw_get_affected_fields(queue);
|
where = skygw_get_affected_fields(queue);
|
||||||
|
|
||||||
if(where != NULL){
|
if(where != NULL){
|
||||||
if(strchr(where,'*')){
|
if(strchr(where,'*') == NULL){
|
||||||
rule_match = false;
|
rule_match = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1414,9 +1417,10 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue)
|
|||||||
rulelist = rulelist->next;
|
rulelist = rulelist->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rule_match == true){
|
if(rule_match){
|
||||||
/**AND rules match TODO: add a way to control what happens if AND matches*/
|
/**AND rules match*/
|
||||||
accept = false;
|
skygw_log_write(LOGFILE_TRACE, "fwfilter: all rules match, query is %s.",accept ? "allowed":"denied");
|
||||||
|
accept = !my_instance->def_op;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryresolved:
|
queryresolved:
|
||||||
|
|||||||
Reference in New Issue
Block a user