diff --git a/conf/kore.conf.example b/conf/kore.conf.example index c6a1517..86b0376 100644 --- a/conf/kore.conf.example +++ b/conf/kore.conf.example @@ -352,7 +352,7 @@ domain localhost { # # Note the directory given must be relative to the root configuration # option. - filemap /files/ static_files + filemap /files/ static_files [auth] } # Example redirect 80->443. diff --git a/include/kore/kore.h b/include/kore/kore.h index 62f2c22..e129fb0 100644 --- a/include/kore/kore.h +++ b/include/kore/kore.h @@ -982,10 +982,11 @@ int kore_msg_register(u_int8_t, /* filemap.c */ void kore_filemap_init(void); void kore_filemap_resolve_paths(void); -int kore_filemap_create(struct kore_domain *, const char *, - const char *); extern char *kore_filemap_ext; extern char *kore_filemap_index; + +struct kore_route *kore_filemap_create(struct kore_domain *, const char *, + const char *, const char *); #endif /* fileref.c */ diff --git a/src/config.c b/src/config.c index 25a7ef3..dac7488 100644 --- a/src/config.c +++ b/src/config.c @@ -1335,21 +1335,21 @@ configure_redirect(char *options) static int configure_filemap(char *options) { - char *argv[3]; + char *argv[4]; if (current_domain == NULL) { kore_log(LOG_ERR, "filemap keyword not in domain context"); return (KORE_RESULT_ERROR); } - kore_split_string(options, " ", argv, 3); + kore_split_string(options, " ", argv, 4); if (argv[0] == NULL || argv[1] == NULL) { kore_log(LOG_ERR, "missing parameters for filemap"); return (KORE_RESULT_ERROR); } - if (!kore_filemap_create(current_domain, argv[1], argv[0])) { + if (!kore_filemap_create(current_domain, argv[1], argv[0], argv[2])) { kore_log(LOG_ERR, "cannot create filemap for %s", argv[1]); return (KORE_RESULT_ERROR); } diff --git a/src/filemap.c b/src/filemap.c index 628b72f..ab6079a 100644 --- a/src/filemap.c +++ b/src/filemap.c @@ -52,8 +52,9 @@ kore_filemap_init(void) TAILQ_INIT(&maps); } -int -kore_filemap_create(struct kore_domain *dom, const char *path, const char *root) +struct kore_route * +kore_filemap_create(struct kore_domain *dom, const char *path, + const char *root, const char *auth) { size_t sz; struct stat st; @@ -64,10 +65,10 @@ kore_filemap_create(struct kore_domain *dom, const char *path, const char *root) sz = strlen(root); if (sz == 0) - return (KORE_RESULT_ERROR); + return (NULL); if (root[0] != '/' || root[sz - 1] != '/') - return (KORE_RESULT_ERROR); + return (NULL); if (worker_privsep.root != NULL) { len = snprintf(fpath, sizeof(fpath), "%s/%s", @@ -82,7 +83,7 @@ kore_filemap_create(struct kore_domain *dom, const char *path, const char *root) if (stat(fpath, &st) == -1) { kore_log(LOG_ERR, "%s: failed to stat '%s': %s", __func__, fpath, errno_s); - return (KORE_RESULT_ERROR); + return (NULL); } len = snprintf(regex, sizeof(regex), "^%s.*$", root); @@ -90,7 +91,15 @@ kore_filemap_create(struct kore_domain *dom, const char *path, const char *root) fatal("kore_filemap_create: buffer too small"); if ((rt = kore_route_create(dom, regex, HANDLER_TYPE_DYNAMIC)) == NULL) - return (KORE_RESULT_ERROR); + return (NULL); + + if (auth != NULL) { + rt->auth = kore_auth_lookup(auth); + if (rt->auth == NULL) { + fatal("filemap for '%s' has unknown auth '%s'", + path, auth); + } + } kore_route_callback(rt, "filemap_resolve"); rt->methods = HTTP_METHOD_GET | HTTP_METHOD_HEAD; @@ -109,7 +118,7 @@ kore_filemap_create(struct kore_domain *dom, const char *path, const char *root) TAILQ_INSERT_TAIL(&maps, entry, list); - return (KORE_RESULT_OK); + return (rt); } void diff --git a/src/python.c b/src/python.c index a2a29ca..5cb032c 100644 --- a/src/python.c +++ b/src/python.c @@ -5396,8 +5396,9 @@ static PyObject * pydomain_filemaps(struct pydomain *domain, PyObject *args) { Py_ssize_t idx; + struct kore_route *rt; const char *url, *path; - PyObject *dict, *key, *value; + PyObject *dict, *key, *value, *auth; if (!PyArg_ParseTuple(args, "O", &dict)) return (NULL); @@ -5409,22 +5410,56 @@ pydomain_filemaps(struct pydomain *domain, PyObject *args) idx = 0; while (PyDict_Next(dict, &idx, &key, &value)) { - if (!PyUnicode_CheckExact(key) || - !PyUnicode_CheckExact(value)) { + if (!PyUnicode_CheckExact(key)) { PyErr_SetString(PyExc_RuntimeError, - "filemap entries not strings"); + "filemap key not a string"); return (NULL); } url = PyUnicode_AsUTF8(key); + + if (!PyUnicode_CheckExact(value) && + !PyTuple_CheckExact(value)) { + PyErr_SetString(PyExc_RuntimeError, + "filemap value can be either be a string or tuple"); + return (NULL); + } + + if (PyTuple_CheckExact(value)) { + auth = PyTuple_GetItem(value, 1); + if (!PyDict_CheckExact(auth)) { + PyErr_SetString(PyExc_RuntimeError, + "filemap value tuple auth is not a dict"); + return (NULL); + } + + value = PyTuple_GetItem(value, 0); + if (!PyUnicode_CheckExact(value)) { + PyErr_SetString(PyExc_RuntimeError, + "filemap value tuple path is invalid"); + return (NULL); + } + } else { + auth = NULL; + } + path = PyUnicode_AsUTF8(value); - if (!kore_filemap_create(domain->config, path, url)) { + rt = kore_filemap_create(domain->config, path, url, NULL); + if (rt == NULL) { PyErr_Format(PyExc_RuntimeError, "failed to create filemap %s->%s for %s", url, path, domain->config->domain); return (NULL); } + + if (auth != NULL) { + if (!python_route_auth(auth, rt)) { + kore_python_log_error("python_route_auth"); + kore_route_free(rt); + return (KORE_RESULT_ERROR); + } + } } Py_RETURN_NONE; diff --git a/tools/kore-serve/src/kore-serve.c b/tools/kore-serve/src/kore-serve.c index 5ad9157..cb57638 100644 --- a/tools/kore-serve/src/kore-serve.c +++ b/tools/kore-serve/src/kore-serve.c @@ -90,6 +90,6 @@ kore_parent_configure(int argc, char *argv[]) dom = kore_domain_new("*"); kore_domain_attach(dom, srv); - if (!kore_filemap_create(dom, rpath, "/")) + if (!kore_filemap_create(dom, rpath, "/", NULL)) fatal("failed to create filemap for %s", rpath); }