Пример #1
0
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;
}
Пример #2
0
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;
}