Add a "return" configuration option.

This hooks into the existing redirection framework but allows you
to quickly deny certain paths with a 403 or other status code.

The snippet below would for example declare a filemap served from 'www'
directory but denying all access to the files under the 'data' directory:

filemap		/	www
deny		/data	403
This commit is contained in:
Joris Vink 2020-03-03 11:28:16 +01:00
parent 9e5e698e4b
commit db31f37ab0
2 changed files with 66 additions and 21 deletions

View File

@ -110,6 +110,7 @@ static int configure_client_verify_depth(char *);
#if !defined(KORE_NO_HTTP)
static int configure_route(char *);
static int configure_filemap(char *);
static int configure_return(char *);
static int configure_redirect(char *);
static int configure_static_handler(char *);
static int configure_dynamic_handler(char *);
@ -192,6 +193,7 @@ static struct {
{ "route", configure_route},
{ "filemap", configure_filemap },
{ "redirect", configure_redirect },
{ "return", configure_return },
{ "static", configure_static_handler },
{ "dynamic", configure_dynamic_handler },
{ "accesslog", configure_accesslog },
@ -1030,6 +1032,37 @@ configure_route(char *options)
return (KORE_RESULT_OK);
}
static int
configure_return(char *options)
{
char *argv[3];
int elm, status, err;
if (current_domain == NULL) {
printf("return outside of domain context\n");
return (KORE_RESULT_ERROR);
}
elm = kore_split_string(options, " ", argv, 3);
if (elm != 2) {
printf("missing parameters for return\n");
return (KORE_RESULT_ERROR);
}
status = kore_strtonum(argv[1], 10, 400, 600, &err);
if (err != KORE_RESULT_OK) {
printf("invalid status code on return (%s)\n", argv[1]);
return (KORE_RESULT_ERROR);
}
if (!http_redirect_add(current_domain, argv[0], status, NULL)) {
printf("invalid regex on return path\n");
return (KORE_RESULT_ERROR);
}
return (KORE_RESULT_OK);
}
static int
configure_redirect(char *options)
{

View File

@ -1500,7 +1500,11 @@ http_redirect_add(struct kore_domain *dom, const char *path, int status,
}
rdr->status = status;
rdr->target = kore_strdup(target);
if (target != NULL)
rdr->target = kore_strdup(target);
else
rdr->target = NULL;
TAILQ_INSERT_TAIL(&dom->redirects, rdr, list);
@ -1525,34 +1529,42 @@ http_check_redirect(struct http_request *req, struct kore_domain *dom)
if (rdr == NULL)
return (KORE_RESULT_ERROR);
uri = NULL;
kore_buf_init(&location, 128);
kore_buf_appendf(&location, "%s", rdr->target);
if (req->query_string != NULL) {
kore_buf_replace_string(&location, "$qs",
req->query_string, strlen(req->query_string));
if (rdr->target) {
kore_buf_appendf(&location, "%s", rdr->target);
if (req->query_string != NULL) {
kore_buf_replace_string(&location, "$qs",
req->query_string, strlen(req->query_string));
}
/* Starts at 1 to skip the full path. */
for (idx = 1; idx < HTTP_CAPTURE_GROUPS - 1; idx++) {
if (req->cgroups[idx].rm_so == -1 ||
req->cgroups[idx].rm_eo == -1)
break;
(void)snprintf(key, sizeof(key), "$%d", idx);
kore_buf_replace_string(&location, key,
req->path + req->cgroups[idx].rm_so,
req->cgroups[idx].rm_eo - req->cgroups[idx].rm_so);
}
uri = kore_buf_stringify(&location, NULL);
}
/* Starts at 1 to skip the full path. */
for (idx = 1; idx < HTTP_CAPTURE_GROUPS - 1; idx++) {
if (req->cgroups[idx].rm_so == -1 ||
req->cgroups[idx].rm_eo == -1)
break;
if (uri)
http_response_header(req, "location", uri);
(void)snprintf(key, sizeof(key), "$%d", idx);
kore_buf_replace_string(&location, key,
req->path + req->cgroups[idx].rm_so,
req->cgroups[idx].rm_eo - req->cgroups[idx].rm_so);
}
uri = kore_buf_stringify(&location, NULL);
http_response_header(req, "location", uri);
http_response(req, rdr->status, NULL, 0);
kore_buf_cleanup(&location);
if (dom->accesslog)
kore_accesslog(req);
return (KORE_RESULT_OK);
}