Ejemplo n.º 1
0
END_TEST

START_TEST (netacl_dup_test) {
  pr_netacl_t *acl, *res;

  res = pr_netacl_dup(NULL, NULL);
  fail_unless(res == NULL, "Failed to handle NULL arguments");
  fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");

  res = pr_netacl_dup(p, NULL);
  fail_unless(res == NULL, "Failed to handle NULL ACL argument");
  fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");

  acl = pr_netacl_create(p, "ALL");
  fail_unless(acl != NULL, "Failed to create ALL ACL");

  res = pr_netacl_dup(NULL, acl);
  fail_unless(res == NULL, "Failed to handle NULL pool");
  fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");

  res = pr_netacl_dup(p, acl);
  fail_unless(res != NULL, "Failed to dup ACL: %s", strerror(errno));
  fail_unless(strcmp(pr_netacl_get_str(p, res), pr_netacl_get_str(p, acl)) == 0,
    "Expected '%s', got '%s'", pr_netacl_get_str(p, acl),
    pr_netacl_get_str(p, res));
}
static bool is_allowed(cmd_rec *cmd, pr_netaddr_t *na) {
    int i;
    config_rec *c;
    array_header *allowed_acls;

    c = find_config(cmd->server->conf, CONF_PARAM, "LMDBAllow", FALSE);
    if(NULL == c)
        return false;

    allowed_acls = c->argv[0];
    if(NULL == allowed_acls) {
        pr_log_auth(PR_LOG_ERR,
          "%s: pr_table_t is NULL. something fatal", MODULE_NAME);
        return false;
    }

#ifdef DEBUG
    pr_table_do(allowed_acls, walk_table, NULL, 0);
#endif

    pr_netacl_t **elts = allowed_acls->elts;
    for (i = 0; i < allowed_acls->nelts; i++) {
        pr_netacl_t *acl = elts[i];
        if(pr_netacl_match(acl, na) == 1) {
            pr_log_auth(PR_LOG_INFO,
                "%s: client IP matched with LMDBAllow '%s'. Skip last process",
                        MODULE_NAME, pr_netacl_get_str(cmd->tmp_pool, acl));
            return true;
        }
    }

    return false;
}
Ejemplo n.º 3
0
pr_class_t *pr_class_match_addr(pr_netaddr_t *addr) {
  pr_class_t *cls;
  pool *tmp_pool;

  if (!addr) {
    errno = EINVAL;
    return NULL;
  }

  tmp_pool = make_sub_pool(permanent_pool);

  for (cls = class_list; cls; cls = cls->cls_next) {
    array_header *acl_list = cls->cls_acls;
    pr_netacl_t **acls = acl_list->elts;
    register int i;
    int next_class = FALSE;

    /* For each ACL rule in this class, compare the rule against the given
     * address.  The address matches the given class depending on the
     * Satisfy setting: if "any", the class matches if any rule matches;
     * if "all", the class matches only if _all_ rules match.
     */
    for (i = 0; i < acl_list->nelts; i++) {
      int res;

      if (next_class)
        break;

      if (acls[i] == NULL)
        continue;

      switch (cls->cls_satisfy) {
        case PR_CLASS_SATISFY_ANY:
          pr_trace_msg(trace_channel, 6,
            "checking addr '%s' (%s) against class '%s' rule: %s "
            "(requires any ACL matching)", pr_netaddr_get_ipstr(addr),
            pr_netaddr_get_dnsstr(addr), cls->cls_name,
            pr_netacl_get_str(tmp_pool, acls[i]));

          res = pr_netacl_match(acls[i], addr);
          if (res == 1) {
            destroy_pool(tmp_pool);
            return cls;
          }
          break;

        case PR_CLASS_SATISFY_ALL:
          pr_trace_msg(trace_channel, 6,
            "checking addr '%s' (%s) against class '%s' ACL: %s "
            "(requires all ACLs matching)", pr_netaddr_get_ipstr(addr),
            pr_netaddr_get_dnsstr(addr), cls->cls_name,
            pr_netacl_get_str(tmp_pool, acls[i]));

          res = pr_netacl_match(acls[i], addr);

          if (res <= 0)
            next_class = TRUE;
          break;
      }
    }

    /* If this is a "Satisfy all" class, and all rules have matched
     * (positively or negatively), then it matches the address.
     */
    if (next_class == FALSE &&
        cls->cls_satisfy == PR_CLASS_SATISFY_ALL &&
        i == acl_list->nelts) {
      destroy_pool(tmp_pool);
      return cls;
    }
  }

  destroy_pool(tmp_pool);

  errno = ENOENT;
  return NULL;
}
Ejemplo n.º 4
0
END_TEST

START_TEST (netacl_get_str_test) {
  pr_netacl_t *acl;
  char *acl_str, *ok;
  const char *res;

  res = pr_netacl_get_str(NULL, NULL);
  fail_unless(res == NULL, "Failed to handle NULL arguments");
  fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");

  res = pr_netacl_get_str(p, NULL);
  fail_unless(res == NULL, "Failed to handle NULL ACL");
  fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");

  acl_str = "all";
  acl = pr_netacl_create(p, acl_str);
  fail_unless(acl != NULL, "Failed to create ACL: %s", strerror(errno));

  res = pr_netacl_get_str(NULL, acl);
  fail_unless(res == NULL, "Failed to handle NULL pool");
  fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");

  ok = "all <all>";
  res = pr_netacl_get_str(p, acl);
  fail_unless(res != NULL, "Failed to get ACL string: %s", strerror(errno));
  fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);

  acl_str = "AlL";
  acl = pr_netacl_create(p, acl_str);
  fail_unless(acl != NULL, "Failed to create ACL: %s", strerror(errno));

  res = pr_netacl_get_str(p, acl);
  fail_unless(res != NULL, "Failed to get ACL string: %s", strerror(errno));
  fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);

  acl_str = "None";
  acl = pr_netacl_create(p, acl_str);
  fail_unless(acl != NULL, "Failed to create ACL: %s", strerror(errno));
 
  ok = "none <none>";
  res = pr_netacl_get_str(p, acl);
  fail_unless(res != NULL, "Failed to get ACL string: %s", strerror(errno));
  fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);

  acl_str = pstrdup(p, "127.0.0.1");
  acl = pr_netacl_create(p, acl_str);
  fail_unless(acl != NULL, "Failed to create ACL: %s", strerror(errno));

  ok = "127.0.0.1 <IP address match>";
  res = pr_netacl_get_str(p, acl);
  fail_unless(res != NULL, "Failed to get ACL string: %s", strerror(errno));
  fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);

  acl_str = pstrdup(p, "!127.0.0.1");
  acl = pr_netacl_create(p, acl_str);
  fail_unless(acl != NULL, "Failed to create ACL: %s", strerror(errno));

  ok = "!127.0.0.1 <IP address match, inverted>";
  res = pr_netacl_get_str(p, acl);
  fail_unless(res != NULL, "Failed to get ACL string: %s", strerror(errno));
  fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);

  acl_str = pstrdup(p, "127.0.0.");
  acl = pr_netacl_create(p, acl_str);
  fail_unless(acl != NULL, "Failed to create ACL: %s", strerror(errno));

  ok = "127.0.0.* <IP address glob>";
  res = pr_netacl_get_str(p, acl);
  fail_unless(res != NULL, "Failed to get ACL string: %s", strerror(errno));
  fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);

  acl_str = pstrdup(p, "localhost");
  acl = pr_netacl_create(p, acl_str);
  fail_unless(acl != NULL, "Failed to create ACL: %s", strerror(errno));

  ok = "localhost <DNS hostname match>";
  res = pr_netacl_get_str(p, acl);
  fail_unless(res != NULL, "Failed to get ACL string: %s", strerror(errno));
  fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);

  acl_str = pstrdup(p, ".castaglia.org");
  acl = pr_netacl_create(p, acl_str);
  fail_unless(acl != NULL, "Failed to create ACL: %s", strerror(errno));

  ok = "*.castaglia.org <DNS hostname glob>";
  res = pr_netacl_get_str(p, acl);
  fail_unless(res != NULL, "Failed to get ACL string: %s", strerror(errno));
  fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);

  acl_str = pstrdup(p, "127.0.0.1/24");
  acl = pr_netacl_create(p, acl_str);
  fail_unless(acl != NULL, "Failed to create ACL: %s", strerror(errno));

  ok = "127.0.0.1/24 <IP address mask, 24-bit mask>";
  res = pr_netacl_get_str(p, acl);
  fail_unless(res != NULL, "Failed to get ACL string: %s", strerror(errno));
  fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);

  acl_str = pstrdup(p, "127.0.0.1/0");
  acl = pr_netacl_create(p, acl_str);
  fail_unless(acl != NULL, "Failed to create ACL: %s", strerror(errno));

  ok = "127.0.0.1/0 <IP address mask, 0-bit mask>";
  res = pr_netacl_get_str(p, acl);
  fail_unless(res != NULL, "Failed to get ACL string: %s", strerror(errno));
  fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);

  acl_str = pstrdup(p, "!127.0.0.1/24");
  acl = pr_netacl_create(p, acl_str);
  fail_unless(acl != NULL, "Failed to create ACL: %s", strerror(errno));

  ok = "!127.0.0.1/24 <IP address mask, 24-bit mask, inverted>";
  res = pr_netacl_get_str(p, acl);
  fail_unless(res != NULL, "Failed to get ACL string: %s", strerror(errno));
  fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);

#ifdef PR_USE_IPV6
  acl_str = pstrdup(p, "::1/24");
  acl = pr_netacl_create(p, acl_str);
  fail_unless(acl != NULL, "Failed to create ACL: %s", strerror(errno));

  ok = "::1/24 <IP address mask, 24-bit mask>";
  res = pr_netacl_get_str(p, acl);
  fail_unless(res != NULL, "Failed to get ACL string: %s", strerror(errno));
  fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);

  acl_str = pstrdup(p, "::1/127");
  acl = pr_netacl_create(p, acl_str);
  fail_unless(acl != NULL, "Failed to create ACL: %s", strerror(errno));

  ok = "::1/127 <IP address mask, 127-bit mask>";
  res = pr_netacl_get_str(p, acl);
  fail_unless(res != NULL, "Failed to get ACL string: %s", strerror(errno));
  fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);

  acl_str = pstrdup(p, "::ffff:127.0.0.1/127");
  acl = pr_netacl_create(p, acl_str);
  fail_unless(acl != NULL, "Failed to create ACL: %s", strerror(errno));

  ok = "::ffff:127.0.0.1/127 <IP address mask, 127-bit mask>";
  res = pr_netacl_get_str(p, acl);
  fail_unless(res != NULL, "Failed to get ACL string: %s", strerror(errno));
  fail_unless(strcmp(res, ok) == 0, "Expected '%s', got '%s'", ok, res);
#endif
}
Ejemplo n.º 5
0
/* Returns 1 if there was a positive match, -1 if there was a negative
 * match, -2 if there was an error, and zero if there was no match at all.
 */
int pr_netacl_match(const pr_netacl_t *acl, const pr_netaddr_t *addr) {
  pool *tmp_pool;

  if (acl == NULL ||
      addr == NULL) {
    errno = EINVAL;
    return -2;
  }

  tmp_pool = make_sub_pool(permanent_pool);

  switch (acl->type) {
    case PR_NETACL_TYPE_ALL:
      pr_trace_msg(trace_channel, 10, "addr '%s' matched rule 'ALL' ('%s')",
        pr_netaddr_get_ipstr(addr), pr_netacl_get_str(tmp_pool, acl));
      destroy_pool(tmp_pool);
      return 1;

    case PR_NETACL_TYPE_NONE:
      pr_trace_msg(trace_channel, 10, "addr '%s' matched rule 'NONE'",
        pr_netaddr_get_ipstr(addr));
      destroy_pool(tmp_pool);
      return -1;

    case PR_NETACL_TYPE_IPMASK:
      pr_trace_msg(trace_channel, 10,
        "checking addr '%s' against IP mask rule '%s'",
        pr_netaddr_get_ipstr(addr), acl->aclstr);

      if (pr_netaddr_ncmp(addr, acl->addr, acl->masklen) == 0) {
        pr_trace_msg(trace_channel, 10, "addr '%s' matched IP mask rule '%s'",
          pr_netaddr_get_ipstr(addr), acl->aclstr);
        destroy_pool(tmp_pool);

        if (acl->negated)
          return -1;

        return 1;

      } else {
        if (acl->negated) {
          destroy_pool(tmp_pool);
          return 1;
        }
      }
      break;

    case PR_NETACL_TYPE_IPMATCH:
      pr_trace_msg(trace_channel, 10,
        "checking addr '%s' against IP address rule '%s'",
        pr_netaddr_get_ipstr(addr), acl->aclstr);

      if (pr_netaddr_cmp(addr, acl->addr) == 0) {
        pr_trace_msg(trace_channel, 10,
          "addr '%s' matched IP address rule '%s'",
          pr_netaddr_get_ipstr(addr), acl->aclstr);
        destroy_pool(tmp_pool);

        if (acl->negated)
          return -1;

        return 1;

      } else {
        if (acl->negated) {
          destroy_pool(tmp_pool);
          return 1;
        }
      }
      break;
 
    case PR_NETACL_TYPE_DNSMATCH:
      pr_trace_msg(trace_channel, 10,
        "checking addr '%s' against DNS name rule '%s'",
        pr_netaddr_get_dnsstr(addr), acl->pattern);

      if (strcmp(pr_netaddr_get_dnsstr(addr), acl->pattern) == 0) {
        pr_trace_msg(trace_channel, 10,
          "addr '%s' (%s) matched DNS name rule '%s'",
          pr_netaddr_get_ipstr(addr), pr_netaddr_get_dnsstr(addr),
          acl->aclstr);
        destroy_pool(tmp_pool);

        if (acl->negated)
          return -1;

        return 1;

      } else {
        if (acl->negated) {
          destroy_pool(tmp_pool);
          return 1;
        }
      }
      break;

    case PR_NETACL_TYPE_IPGLOB:
      pr_trace_msg(trace_channel, 10,
        "checking addr '%s' against IP glob rule '%s'",
        pr_netaddr_get_ipstr(addr), acl->aclstr);

      if (pr_netaddr_fnmatch(addr, acl->pattern,
          PR_NETADDR_MATCH_IP) == TRUE) {
        pr_trace_msg(trace_channel, 10,
          "addr '%s' matched IP glob rule '%s'",
          pr_netaddr_get_ipstr(addr), acl->aclstr);
        destroy_pool(tmp_pool);

        if (acl->negated)
          return -1;

        return 1;

      } else {
        if (acl->negated) {
          destroy_pool(tmp_pool);
          return 1;
        }
      }
      break;

    case PR_NETACL_TYPE_DNSGLOB:
      if (ServerUseReverseDNS) {
        pr_trace_msg(trace_channel, 10,
          "checking addr '%s' against DNS glob rule '%s'",
          pr_netaddr_get_dnsstr(addr), acl->pattern);

        if (pr_netaddr_fnmatch(addr, acl->pattern,
            PR_NETADDR_MATCH_DNS) == TRUE) {
          pr_trace_msg(trace_channel, 10,
            "addr '%s' (%s) matched DNS glob rule '%s'",
            pr_netaddr_get_ipstr(addr), pr_netaddr_get_dnsstr(addr),
            acl->aclstr);
          destroy_pool(tmp_pool);

          if (acl->negated)
            return -1;

          return 1;

        } else {
          if (acl->negated) {
            destroy_pool(tmp_pool);
            return 1;
          }
        }

      } else {
        pr_trace_msg(trace_channel, 10,
          "skipping comparing addr '%s' (%s) against DNS glob rule '%s' "
          "because UseReverseDNS is off", pr_netaddr_get_ipstr(addr),
          pr_netaddr_get_dnsstr(addr), acl->aclstr);
      }
      break;
  }

  destroy_pool(tmp_pool);
  return 0;
}