Add support for wildcard in mysql_query_rules.client_addr #1450
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.
This commit is contained in:
Родитель
52fdaa15d3
Коммит
d1a14e6c12
|
@ -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;
|
||||
|
|
|
@ -7005,6 +7005,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,
|
||||
|
|
|
@ -493,7 +493,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;
|
||||
|
@ -952,9 +968,19 @@ __internal_loop:
|
|||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче