Skip to content

Commit

Permalink
Add support for wildcard in mysql_query_rules.client_addr sysown#1450
Browse files Browse the repository at this point in the history
Input validation:
- client_addr not longer than INET6_ADDRSTRLEN
- % allowed only at the end of client_addr

Query rule itself remembers if there is a wildcard or not.
If there is a wildcard compares string till the wildcard.
If client_addr=='%' , it is a match all.
  • Loading branch information
renecannao authored and pondix committed Apr 11, 2018
1 parent 405f836 commit c15ee49
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 3 deletions.
1 change: 1 addition & 0 deletions include/query_processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct _Query_Processor_rule_t {
char *schemaname;
int flagIN;
char *client_addr;
int client_addr_wildcard_position;
char *proxy_addr;
int proxy_port;
uint64_t digest;
Expand Down
16 changes: 16 additions & 0 deletions lib/ProxySQL_Admin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7070,6 +7070,22 @@ char * ProxySQL_Admin::load_mysql_query_rules_to_runtime() {
QP_rule_t * nqpr;
for (std::vector<SQLite3_row *>::iterator it = resultset->rows.begin() ; it != resultset->rows.end(); ++it) {
SQLite3_row *r=*it;
if (r->fields[4]) {
char *pct = NULL;
if (strlen(r->fields[4]) >= INET6_ADDRSTRLEN) {
proxy_error("Query rule with rule_id=%s has an invalid client_addr: %s\n", r->fields[0], r->fields[4]);
continue;
}
pct = strchr(r->fields[4],'%');
if (pct) { // there is a wildcard
if (strlen(pct) == 1) {
// % is at the end of the string, good
} else {
proxy_error("Query rule with rule_id=%s has a wildcard that is not at the end of client_addr: %s\n", r->fields[0], r->fields[4]);
continue;
}
}
}
nqpr=GloQPro->new_query_rule(
atoi(r->fields[0]), // rule_id
true,
Expand Down
32 changes: 29 additions & 3 deletions lib/Query_Processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,23 @@ QP_rule_t * Query_Processor::new_query_rule(int rule_id, bool active, char *user
newQR->regex_engine2=NULL;
newQR->hits=0;

newQR->client_addr_wildcard_position = -1; // not existing by default
newQR->client_addr=(client_addr ? strdup(client_addr) : NULL);
if (newQR->client_addr) {
char *pct = strchr(newQR->client_addr,'%');
if (pct) { // there is a wildcard . We assume Admin did already all the input validation
if (pct == newQR->client_addr) {
// client_addr == '%'
// % is at the end of the string, but also at the beginning
// becoming a catch all
newQR->client_addr_wildcard_position = 0;
} else {
// this math is valid also if (pct == newQR->client_addr)
// but we separate it to clarify that client_addr_wildcard_position is a match all
newQR->client_addr_wildcard_position = strlen(newQR->client_addr) - strlen(pct);
}
}
}
newQR->proxy_addr=(proxy_addr ? strdup(proxy_addr) : NULL);
newQR->proxy_port=proxy_port;
newQR->log=log;
Expand Down Expand Up @@ -957,9 +973,19 @@ Query_Processor_Output * Query_Processor::process_mysql_query(MySQL_Session *ses
// match on client address
if (qr->client_addr && strlen(qr->client_addr)) {
if (sess->client_myds->addr.addr) {
if (strcmp(qr->client_addr,sess->client_myds->addr.addr)!=0) {
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "query rule %d has no matching client_addr\n", qr->rule_id);
continue;
if (qr->client_addr_wildcard_position == -1) { // no wildcard , old algorithm
if (strcmp(qr->client_addr,sess->client_myds->addr.addr)!=0) {
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "query rule %d has no matching client_addr\n", qr->rule_id);
continue;
}
} else if (qr->client_addr_wildcard_position==0) {
// catch all!
// therefore we have a match
} else { // client_addr_wildcard_position > 0
if (strncmp(qr->client_addr,sess->client_myds->addr.addr,qr->client_addr_wildcard_position)!=0) {
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "query rule %d has no matching client_addr\n", qr->rule_id);
continue;
}
}
}
}
Expand Down

0 comments on commit c15ee49

Please sign in to comment.