END_TEST START_TEST (regexp_get_pattern_test) { pr_regex_t *pre = NULL; int res; const char *str; char *pattern; str = pr_regexp_get_pattern(NULL); fail_unless(str == NULL, "Failed to handle null arguments"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL, strerror(errno), errno); pre = pr_regexp_alloc(NULL); str = pr_regexp_get_pattern(pre); fail_unless(str == NULL, "Failed to handle null pattern"); fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT, strerror(errno), errno); pattern = "^foo"; res = pr_regexp_compile(pre, pattern, 0); fail_unless(res == 0, "Failed to compile regex pattern '%s'", pattern); str = pr_regexp_get_pattern(pre); fail_unless(str != NULL, "Failed to get regex pattern: %s", strerror(errno)); fail_unless(strcmp(str, pattern) == 0, "Expected '%s', got '%s'", pattern, str); pr_regexp_free(NULL, pre); }
static int regexp_exec_posix(pr_regex_t *pre, const char *str, size_t nmatches, regmatch_t *matches, int flags) { int res; pr_trace_msg(trace_channel, 9, "executing POSIX regex '%s' against subject '%s'", pr_regexp_get_pattern(pre), str); res = regexec(pre->re, str, nmatches, matches, flags); return res; }
static int forward_dst_filter(pool *p, const char *hostport) { #ifdef PR_USE_REGEX config_rec *c; pr_regex_t *pre; int negated = FALSE, res; c = find_config(main_server->conf, CONF_PARAM, "ProxyForwardTo", FALSE); if (c == NULL) { return 0; } pre = c->argv[0]; negated = *((int *) c->argv[1]); res = pr_regexp_exec(pre, hostport, 0, NULL, 0, 0, 0); if (res == 0) { /* Pattern matched */ if (negated == TRUE) { (void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION, "host/port '%.100s' matched ProxyForwardTo !%s, rejecting", hostport, pr_regexp_get_pattern(pre)); errno = EPERM; return -1; } } else { /* Pattern NOT matched */ if (negated == FALSE) { (void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION, "host/port '%.100s' did not match ProxyForwardTo %s, rejecting", hostport, pr_regexp_get_pattern(pre)); errno = EPERM; return -1; } } #endif /* PR_USE_REGEX */ return 0; }
static int regexp_exec_pcre(pr_regex_t *pre, const char *str, size_t nmatches, regmatch_t *matches, int flags, unsigned long match_limit, unsigned long match_limit_recursion) { if (pre->pcre != NULL) { int res; size_t str_len; str_len = strlen(str); /* Use the default match limits, if set and if the caller did not * explicitly provide limits. */ if (match_limit == 0) { match_limit = pcre_match_limit; } if (match_limit_recursion == 0) { match_limit_recursion = pcre_match_limit_recursion; } if (match_limit > 0) { if (pre->pcre_extra == NULL) { pre->pcre_extra = pcalloc(pre->regex_pool, sizeof(pcre_extra)); } pre->pcre_extra->flags |= PCRE_EXTRA_MATCH_LIMIT; pre->pcre_extra->match_limit = match_limit; } if (match_limit_recursion > 0) { if (pre->pcre_extra == NULL) { pre->pcre_extra = pcalloc(pre->regex_pool, sizeof(pcre_extra)); } pre->pcre_extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; pre->pcre_extra->match_limit_recursion = match_limit_recursion; } pr_trace_msg(trace_channel, 9, "executing PCRE regex '%s' against subject '%s'", pr_regexp_get_pattern(pre), str); res = pcre_exec(pre->pcre, pre->pcre_extra, str, str_len, 0, flags, NULL, 0); if (res < 0) { if (pr_trace_get_level(trace_channel) >= 9) { const char *reason = "unknown"; switch (res) { case PCRE_ERROR_NOMATCH: reason = "subject did not match pattern"; break; case PCRE_ERROR_NULL: reason = "null regex or subject"; break; case PCRE_ERROR_BADOPTION: reason = "unsupported options bit"; break; case PCRE_ERROR_BADMAGIC: reason = "bad magic number in regex"; break; case PCRE_ERROR_UNKNOWN_OPCODE: case PCRE_ERROR_INTERNAL: reason = "internal PCRE error or corrupted regex"; break; case PCRE_ERROR_NOMEMORY: reason = "not enough memory for backreferences"; break; case PCRE_ERROR_MATCHLIMIT: reason = "match limit reached/exceeded"; break; case PCRE_ERROR_RECURSIONLIMIT: reason = "match limit recursion reached/exceeded"; break; case PCRE_ERROR_BADUTF8: reason = "invalid UTF8 subject used"; break; case PCRE_ERROR_PARTIAL: reason = "subject matched only partially; PCRE_PARTIAL flag not used"; break; } pr_trace_msg(trace_channel, 9, "PCRE regex '%s' failed to match subject '%s': %s", pr_regexp_get_pattern(pre), str, reason); } else { pr_trace_msg(trace_channel, 9, "PCRE regex '%s' successfully match subject '%s'", pr_regexp_get_pattern(pre), str); } } return res; } errno = EINVAL; return -1; }