mirror of
https://github.com/jorisvink/kore
synced 2025-03-09 12:39:01 -04:00
Allow authenticators on filemaps.
This commit introduces the ability to add authenticators to filemaps. Just like in normal routes, the authenticators will be resolved first before allowing access to the filemap entries. Configuration wise, the authenticator is an optional value after the filemap config directive: filemap / webroot myauth In the Python API you can now pass the authenticator for a filemap entry but turning the value of the filemap into a tuple with the first entry being the path and the second being the auth dict: AUTH AUTH={ "type": "cookie", "value": "cookiename", "redirect": "/auth/", "verify": verify_cookie } domain.filemaps({ "/css/": "webroot/css", "/secret/": ("webroot/secret", AUTH) })
This commit is contained in:
parent
8a0aad31fe
commit
73be741bfd
@ -352,7 +352,7 @@ domain localhost {
|
|||||||
#
|
#
|
||||||
# Note the directory given must be relative to the root configuration
|
# Note the directory given must be relative to the root configuration
|
||||||
# option.
|
# option.
|
||||||
filemap /files/ static_files
|
filemap /files/ static_files [auth]
|
||||||
}
|
}
|
||||||
|
|
||||||
# Example redirect 80->443.
|
# Example redirect 80->443.
|
||||||
|
@ -982,10 +982,11 @@ int kore_msg_register(u_int8_t,
|
|||||||
/* filemap.c */
|
/* filemap.c */
|
||||||
void kore_filemap_init(void);
|
void kore_filemap_init(void);
|
||||||
void kore_filemap_resolve_paths(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_ext;
|
||||||
extern char *kore_filemap_index;
|
extern char *kore_filemap_index;
|
||||||
|
|
||||||
|
struct kore_route *kore_filemap_create(struct kore_domain *, const char *,
|
||||||
|
const char *, const char *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* fileref.c */
|
/* fileref.c */
|
||||||
|
@ -1335,21 +1335,21 @@ configure_redirect(char *options)
|
|||||||
static int
|
static int
|
||||||
configure_filemap(char *options)
|
configure_filemap(char *options)
|
||||||
{
|
{
|
||||||
char *argv[3];
|
char *argv[4];
|
||||||
|
|
||||||
if (current_domain == NULL) {
|
if (current_domain == NULL) {
|
||||||
kore_log(LOG_ERR, "filemap keyword not in domain context");
|
kore_log(LOG_ERR, "filemap keyword not in domain context");
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
kore_split_string(options, " ", argv, 3);
|
kore_split_string(options, " ", argv, 4);
|
||||||
|
|
||||||
if (argv[0] == NULL || argv[1] == NULL) {
|
if (argv[0] == NULL || argv[1] == NULL) {
|
||||||
kore_log(LOG_ERR, "missing parameters for filemap");
|
kore_log(LOG_ERR, "missing parameters for filemap");
|
||||||
return (KORE_RESULT_ERROR);
|
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]);
|
kore_log(LOG_ERR, "cannot create filemap for %s", argv[1]);
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
}
|
}
|
||||||
|
@ -52,8 +52,9 @@ kore_filemap_init(void)
|
|||||||
TAILQ_INIT(&maps);
|
TAILQ_INIT(&maps);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
struct kore_route *
|
||||||
kore_filemap_create(struct kore_domain *dom, const char *path, const char *root)
|
kore_filemap_create(struct kore_domain *dom, const char *path,
|
||||||
|
const char *root, const char *auth)
|
||||||
{
|
{
|
||||||
size_t sz;
|
size_t sz;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@ -64,10 +65,10 @@ kore_filemap_create(struct kore_domain *dom, const char *path, const char *root)
|
|||||||
|
|
||||||
sz = strlen(root);
|
sz = strlen(root);
|
||||||
if (sz == 0)
|
if (sz == 0)
|
||||||
return (KORE_RESULT_ERROR);
|
return (NULL);
|
||||||
|
|
||||||
if (root[0] != '/' || root[sz - 1] != '/')
|
if (root[0] != '/' || root[sz - 1] != '/')
|
||||||
return (KORE_RESULT_ERROR);
|
return (NULL);
|
||||||
|
|
||||||
if (worker_privsep.root != NULL) {
|
if (worker_privsep.root != NULL) {
|
||||||
len = snprintf(fpath, sizeof(fpath), "%s/%s",
|
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) {
|
if (stat(fpath, &st) == -1) {
|
||||||
kore_log(LOG_ERR, "%s: failed to stat '%s': %s", __func__,
|
kore_log(LOG_ERR, "%s: failed to stat '%s': %s", __func__,
|
||||||
fpath, errno_s);
|
fpath, errno_s);
|
||||||
return (KORE_RESULT_ERROR);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
len = snprintf(regex, sizeof(regex), "^%s.*$", root);
|
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");
|
fatal("kore_filemap_create: buffer too small");
|
||||||
|
|
||||||
if ((rt = kore_route_create(dom, regex, HANDLER_TYPE_DYNAMIC)) == NULL)
|
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");
|
kore_route_callback(rt, "filemap_resolve");
|
||||||
rt->methods = HTTP_METHOD_GET | HTTP_METHOD_HEAD;
|
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);
|
TAILQ_INSERT_TAIL(&maps, entry, list);
|
||||||
|
|
||||||
return (KORE_RESULT_OK);
|
return (rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
45
src/python.c
45
src/python.c
@ -5396,8 +5396,9 @@ static PyObject *
|
|||||||
pydomain_filemaps(struct pydomain *domain, PyObject *args)
|
pydomain_filemaps(struct pydomain *domain, PyObject *args)
|
||||||
{
|
{
|
||||||
Py_ssize_t idx;
|
Py_ssize_t idx;
|
||||||
|
struct kore_route *rt;
|
||||||
const char *url, *path;
|
const char *url, *path;
|
||||||
PyObject *dict, *key, *value;
|
PyObject *dict, *key, *value, *auth;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O", &dict))
|
if (!PyArg_ParseTuple(args, "O", &dict))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@ -5409,22 +5410,56 @@ pydomain_filemaps(struct pydomain *domain, PyObject *args)
|
|||||||
|
|
||||||
idx = 0;
|
idx = 0;
|
||||||
while (PyDict_Next(dict, &idx, &key, &value)) {
|
while (PyDict_Next(dict, &idx, &key, &value)) {
|
||||||
if (!PyUnicode_CheckExact(key) ||
|
if (!PyUnicode_CheckExact(key)) {
|
||||||
!PyUnicode_CheckExact(value)) {
|
|
||||||
PyErr_SetString(PyExc_RuntimeError,
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
"filemap entries not strings");
|
"filemap key not a string");
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
url = PyUnicode_AsUTF8(key);
|
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);
|
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,
|
PyErr_Format(PyExc_RuntimeError,
|
||||||
"failed to create filemap %s->%s for %s",
|
"failed to create filemap %s->%s for %s",
|
||||||
url, path, domain->config->domain);
|
url, path, domain->config->domain);
|
||||||
return (NULL);
|
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;
|
Py_RETURN_NONE;
|
||||||
|
@ -90,6 +90,6 @@ kore_parent_configure(int argc, char *argv[])
|
|||||||
dom = kore_domain_new("*");
|
dom = kore_domain_new("*");
|
||||||
kore_domain_attach(dom, srv);
|
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);
|
fatal("failed to create filemap for %s", rpath);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user