static int check_geoip_filters(geoip_policy_e policy) { int matched_allow_filter = -1, allow_conn = 0; #if PR_USE_REGEX config_rec *c; c = find_config(main_server->conf, CONF_PARAM, "GeoIPAllowFilter", FALSE); while (c) { int filter_id, res; pr_regex_t *filter_re; const char *filter_name, *filter_pattern, *filter_value; pr_signals_handle(); if (matched_allow_filter == -1) { matched_allow_filter = FALSE; } filter_id = *((int *) c->argv[0]); filter_pattern = c->argv[1]; filter_re = c->argv[2]; filter_value = get_geoip_filter_value(filter_id); if (filter_value == NULL) { c = find_config_next(c, c->next, CONF_PARAM, "GeoIPAllowFilter", FALSE); continue; } filter_name = get_geoip_filter_name(filter_id); res = pr_regexp_exec(filter_re, filter_value, 0, NULL, 0, 0, 0); pr_trace_msg(trace_channel, 12, "%s filter value %s %s GeoIPAllowFilter pattern '%s'", filter_name, filter_value, res == 0 ? "matched" : "did not match", filter_pattern); if (res == 0) { matched_allow_filter = TRUE; break; } (void) pr_log_writefile(geoip_logfd, MOD_GEOIP_VERSION, "%s filter value '%s' did not match GeoIPAllowFilter pattern '%s'", filter_name, filter_value, filter_pattern); c = find_config_next(c, c->next, CONF_PARAM, "GeoIPAllowFilter", FALSE); } c = find_config(main_server->conf, CONF_PARAM, "GeoIPDenyFilter", FALSE); while (c) { int filter_id, res; pr_regex_t *filter_re; const char *filter_name, *filter_pattern, *filter_value; pr_signals_handle(); filter_id = *((int *) c->argv[0]); filter_pattern = c->argv[1]; filter_re = c->argv[2]; filter_value = get_geoip_filter_value(filter_id); if (filter_value == NULL) { c = find_config_next(c, c->next, CONF_PARAM, "GeoIPDenyFilter", FALSE); continue; } filter_name = get_geoip_filter_name(filter_id); res = pr_regexp_exec(filter_re, filter_value, 0, NULL, 0, 0, 0); pr_trace_msg(trace_channel, 12, "%s filter value %s %s GeoIPDenyFilter pattern '%s'", filter_name, filter_value, res == 0 ? "matched" : "did not match", filter_pattern); if (res == 0) { (void) pr_log_writefile(geoip_logfd, MOD_GEOIP_VERSION, "%s filter value '%s' matched GeoIPDenyFilter pattern '%s'", filter_name, filter_value, filter_pattern); return -1; } c = find_config_next(c, c->next, CONF_PARAM, "GeoIPDenyFilter", FALSE); } #endif /* !HAVE_REGEX_H or !HAVE_REGCOMP */ switch (policy) { case GEOIP_POLICY_ALLOW_DENY: allow_conn = 0; break; case GEOIP_POLICY_DENY_ALLOW: if (matched_allow_filter == FALSE) { /* If we have not explicitly matched any allow filters, then * reject the connection. */ allow_conn = -1; } break; } return allow_conn; }
static int check_geoip_filters(geoip_policy_e policy) { int allow_conn = 0, matched_allow_filter = -1, matched_deny_filter = -1; #if PR_USE_REGEX config_rec *c; c = find_config(main_server->conf, CONF_PARAM, "GeoIPAllowFilter", FALSE); while (c != NULL) { register unsigned int i; int matched = TRUE; array_header *filters; pr_signals_handle(); if (matched_allow_filter == -1) { matched_allow_filter = FALSE; } filters = c->argv[0]; for (i = 0; i < filters->nelts; i++) { int filter_id, res; struct geoip_filter *filter; pr_regex_t *filter_re; const char *filter_name, *filter_pattern, *filter_value; filter = ((struct geoip_filter **) filters->elts)[i]; filter_id = filter->filter_id; filter_pattern = filter->filter_pattern; filter_re = filter->filter_re; filter_value = get_geoip_filter_value(filter_id); if (filter_value == NULL) { matched = FALSE; break; } filter_name = get_geoip_filter_name(filter_id); res = pr_regexp_exec(filter_re, filter_value, 0, NULL, 0, 0, 0); pr_trace_msg(trace_channel, 12, "%s filter value %s %s GeoIPAllowFilter pattern '%s'", filter_name, filter_value, res == 0 ? "matched" : "did not match", filter_pattern); if (res == 0) { (void) pr_log_writefile(geoip_logfd, MOD_GEOIP_VERSION, "%s filter value '%s' matched GeoIPAllowFilter pattern '%s'", filter_name, filter_value, filter_pattern); } else { (void) pr_log_writefile(geoip_logfd, MOD_GEOIP_VERSION, "%s filter value '%s' did not match GeoIPAllowFilter pattern '%s'", filter_name, filter_value, filter_pattern); matched = FALSE; break; } } if (matched == TRUE) { matched_allow_filter = TRUE; break; } c = find_config_next(c, c->next, CONF_PARAM, "GeoIPAllowFilter", FALSE); } c = find_config(main_server->conf, CONF_PARAM, "GeoIPDenyFilter", FALSE); while (c != NULL) { register unsigned int i; int matched = TRUE; array_header *filters; pr_signals_handle(); if (matched_deny_filter == -1) { matched_deny_filter = FALSE; } filters = c->argv[0]; for (i = 0; i < filters->nelts; i++) { int filter_id, res; struct geoip_filter *filter; pr_regex_t *filter_re; const char *filter_name, *filter_pattern, *filter_value; filter = ((struct geoip_filter **) filters->elts)[i]; filter_id = filter->filter_id; filter_pattern = filter->filter_pattern; filter_re = filter->filter_re; filter_value = get_geoip_filter_value(filter_id); if (filter_value == NULL) { matched = FALSE; break; } filter_name = get_geoip_filter_name(filter_id); res = pr_regexp_exec(filter_re, filter_value, 0, NULL, 0, 0, 0); pr_trace_msg(trace_channel, 12, "%s filter value %s %s GeoIPDenyFilter pattern '%s'", filter_name, filter_value, res == 0 ? "matched" : "did not match", filter_pattern); if (res == 0) { (void) pr_log_writefile(geoip_logfd, MOD_GEOIP_VERSION, "%s filter value '%s' matched GeoIPDenyFilter pattern '%s'", filter_name, filter_value, filter_pattern); } else { (void) pr_log_writefile(geoip_logfd, MOD_GEOIP_VERSION, "%s filter value '%s' did not match GeoIPDenyFilter pattern '%s'", filter_name, filter_value, filter_pattern); matched = FALSE; break; } } if (matched == TRUE) { matched_deny_filter = TRUE; break; } c = find_config_next(c, c->next, CONF_PARAM, "GeoIPDenyFilter", FALSE); } #endif /* !HAVE_REGEX_H or !HAVE_REGCOMP */ switch (policy) { case GEOIP_POLICY_ALLOW_DENY: if (matched_deny_filter == TRUE && matched_allow_filter != TRUE) { /* If we explicitly matched any deny filters AND have NOT explicitly * matched any allow filters, the connection is rejected, otherwise, * it is allowed. */ (void) pr_log_writefile(geoip_logfd, MOD_GEOIP_VERSION, "client matched GeoIPDenyFilter, rejecting connection"); allow_conn = -1; } else { pr_trace_msg(trace_channel, 9, "allowing client connection (policy 'allow,deny')"); } break; case GEOIP_POLICY_DENY_ALLOW: if (matched_allow_filter == FALSE) { /* If we have not explicitly matched any allow filters, then * reject the connection. */ (void) pr_log_writefile(geoip_logfd, MOD_GEOIP_VERSION, "client did not match any GeoIPAllowFilters, rejecting connection"); allow_conn = -1; } else { pr_trace_msg(trace_channel, 9, "allowing client connection (policy 'deny,allow')"); } break; } return allow_conn; }