diff options
Diffstat (limited to 'src/config')
-rw-r--r-- | src/config/deps-exe/tipidee-config | 1 | ||||
-rw-r--r-- | src/config/headers.c | 80 | ||||
-rw-r--r-- | src/config/lexparse.c | 24 | ||||
-rw-r--r-- | src/config/repo.c | 4 | ||||
-rw-r--r-- | src/config/tipidee-config-internal.h | 23 | ||||
-rw-r--r-- | src/config/util.c | 15 |
6 files changed, 115 insertions, 32 deletions
diff --git a/src/config/deps-exe/tipidee-config b/src/config/deps-exe/tipidee-config index 55cf760..2e844d8 100644 --- a/src/config/deps-exe/tipidee-config +++ b/src/config/deps-exe/tipidee-config @@ -1,3 +1,4 @@ +util.o node.o repo.o conftree.o diff --git a/src/config/headers.c b/src/config/headers.c index 7bbb573..b080390 100644 --- a/src/config/headers.c +++ b/src/config/headers.c @@ -1,10 +1,37 @@ /* ISC license. */ +#include <string.h> +#include <ctype.h> + +#include <skalibs/strerr.h> #include <skalibs/genalloc.h> #include <skalibs/avltree.h> +#include <tipidee/config.h> #include "tipidee-config-internal.h" +struct builtinheaders_s +{ + char const *key ; + char const *value ; + uint8_t overridable : 1 ; +} ; + +static struct builtinheaders_s const builtinheaders[] = +{ + { .key = "Accept-Ranges", .value = "none", .overridable = 0 }, + { .key = "Cache-Control", .value = "private", .overridable = 1 }, + { .key = "Connection", .value = 0, .overridable = 0 }, + { .key = "Content-Security-Policy", .value = "default-src 'self'; style-src 'self' 'unsafe-inline';", .overridable = 1 }, + { .key = "Date", .value = 0, .overridable = 0 }, + { .key = "Referrer-Policy", .value = "no-referrer-when-downgrade", .overridable = 1 }, + { .key = "Server", .value = "tipidee/" TIPIDEE_VERSION, .overridable = 0 }, + { .key = "Status", .value = 0, .overridable = 0 }, + { .key = "Vary", .value = "Accept-Encoding", .overridable = 0 }, + { .key = "X-Content-Type-Options", .value = "nosniff", .overridable = 1 }, + { .key = "X-Frame-Options", .value = "DENY", .overridable = 1 } +} ; + static stralloc headers_storage = GENALLOC_ZERO ; static repo headers = \ @@ -14,14 +41,21 @@ static repo headers = \ .storage = &headers_storage \ } ; -void header_start (node *node, char const *key, size_t filepos, uint32_t line) +int header_allowed (char const *key) { - return node_start(&headers_storage, node, key, filepos, line) ; + struct builtinheaders_s const *p = BSEARCH(struct builtinheaders_s, key, builtinheaders) ; + return !p || p->overridable ; } -void header_add (node *node, char const *s, size_t len) +void header_canonize (char *key) { - return node_add(&headers_storage, node, s, len) ; + int h = 1 ; + size_t len = strlen(key) ; + for (size_t i = 0 ; i < len ; i++) + { + key[i] = h ? toupper(key[i]) : tolower(key[i]) ; + h = key[i] == '-' ; + } } node const *headers_search (char const *key) @@ -29,18 +63,46 @@ node const *headers_search (char const *key) return repo_search(&headers, key) ; } -void headers_add (node const *node) +void headers_add (char const *key, char const *value, uint8_t options, size_t filepos, uint32_t line) { - return repo_add(&headers, node) ; + node node ; + node_start(&headers_storage, &node, key, filepos, line) ; + node_add(&headers_storage, &node, options & 1 ? "\1" : "", 1) ; + node_add(&headers_storage, &node, value, strlen(value) + 1) ; + repo_add(&headers, &node) ; +} + +static void headers_defaults (node *node) +{ + for (size_t i = 0 ; i < sizeof(builtinheaders) / sizeof(struct builtinheaders_s) ; i++) + { + struct builtinheaders_s const *p = builtinheaders + i ; + if (!p->value) continue ; + if (p->overridable && headers_search(p->key)) continue ; + confnode_add(node, p->key, strlen(p->key) + 1) ; + confnode_add(node, p->overridable ? "\1" : "", 1) ; + confnode_add(node, p->value, strlen(p->value) + 1) ; + } } static int header_write (uint32_t d, unsigned int h, void *data) { + node *confnode = data ; + node *const header = genalloc_s(node, &headers.ga) + d ; + (void)h ; + confnode_add(confnode, headers_storage.s + header->key, header->keylen + 1) ; + confnode_add(confnode, headers_storage.s + header->data, header->datalen + 1) ; return 1 ; } -int headers_write (void) +void headers_finish (void) { - if (!avltree_iter(&headers.tree, &header_write, 0)) return 0 ; - return 1 ; + node node ; + confnode_start(&node, "G:response-headers", 0, 0) ; + headers_defaults(&node) ; + (void)avltree_iter(&headers.tree, &header_write, &node) ; + conftree_add(&node) ; + avltree_free(&headers.tree) ; + genalloc_free(node, &headers.ga) ; + stralloc_free(&headers_storage) ; } diff --git a/src/config/lexparse.c b/src/config/lexparse.c index 5fb9b71..27a62df 100644 --- a/src/config/lexparse.c +++ b/src/config/lexparse.c @@ -2,7 +2,6 @@ #include <stdint.h> #include <string.h> -#include <stdlib.h> #include <errno.h> #include <skalibs/uint32.h> @@ -65,27 +64,32 @@ struct directive_s enum token_e token ; } ; -static int keycmp (void const *a, void const *b) +static void conftree_checkunique (char const *key, mdt const *md) { - return strcmp((char const *)a, ((struct directive_s const *)b)->s) ; + node const *node = conftree_search(key) ; + if (node) + { + char fmt[UINT32_FMT] ; + fmt[uint32_fmt(fmt, node->line)] = 0 ; + strerr_diefn(1, 12, "duplicate ", "key ", key, " in file ", g.storage.s + md->filepos, " line ", md->linefmt, ", previously defined", " in file ", g.storage.s + node->filepos, " line ", fmt) ; + } } -#define BSEARCH(type, key, array) bsearch(key, (array), sizeof(array)/sizeof(type), sizeof(type), (int (*)(void const *, void const *))&keycmp) -static void check_unique (char const *key, mdt const *md) +static void headers_checkunique (char const *key, mdt const *md) { - node const *node = conftree_search(key) ; + node const *node = headers_search(key) ; if (node) { char fmt[UINT32_FMT] ; fmt[uint32_fmt(fmt, node->line)] = 0 ; - strerr_diefn(1, 11, "duplicate key ", key, " in file ", g.storage.s + md->filepos, " line ", md->linefmt, ", previously defined", " in file ", g.storage.s + node->filepos, " line ", fmt) ; + strerr_diefn(1, 12, "duplicate ", "header ", key, " in file ", g.storage.s + md->filepos, " line ", md->linefmt, ", previously defined", " in file ", g.storage.s + node->filepos, " line ", fmt) ; } } static void add_unique (char const *key, char const *value, size_t valuelen, mdt const *md) { node node ; - check_unique(key, md) ; + conftree_checkunique(key, md) ; confnode_start(&node, key, md->filepos, md->line) ; confnode_add(&node, value, valuelen) ; conftree_add(&node) ; @@ -124,7 +128,7 @@ static inline void parse_global (char const *s, size_t const *word, size_t n, md case 1 : /* argv */ { node node ; - check_unique(gl->key, md) ; + conftree_checkunique(gl->key, md) ; confnode_start(&node, gl->key, md->filepos, md->line) ; for (size_t i = 1 ; i < n ; i++) confnode_add(&node, s + word[i], strlen(s + word[i]) + 1) ; @@ -218,7 +222,7 @@ static inline void parse_redirect (char const *s, size_t const *word, size_t n, memcpy(key + 2, domain, domainlen) ; memcpy(key + 2 + domainlen, s + word[0], urlen) ; key[2 + domainlen + urlen] = 0 ; - check_unique(key, md) ; + conftree_checkunique(key, md) ; confnode_start(&node, key, md->filepos, md->line) ; key[0] = '@' | i ; confnode_add(&node, &key[0], 1) ; diff --git a/src/config/repo.c b/src/config/repo.c index a3ba390..9b411e8 100644 --- a/src/config/repo.c +++ b/src/config/repo.c @@ -26,10 +26,10 @@ node const *repo_search (repo const *r, char const *key) return avltree_search(&r->tree, key, &i) ? genalloc_s(node const, &r->ga) + i : 0 ; } -void repo_add (repo *r, node const *node) +void repo_add (repo *r, node const *nod) { uint32_t i = genalloc_len(node, &r->ga) ; - if (!genalloc_append(node, &r->ga, node)) dienomem() ; + if (!genalloc_append(node, &r->ga, nod)) dienomem() ; if (!avltree_insert(&r->tree, i)) dienomem() ; } diff --git a/src/config/tipidee-config-internal.h b/src/config/tipidee-config-internal.h index 190ac45..3508771 100644 --- a/src/config/tipidee-config-internal.h +++ b/src/config/tipidee-config-internal.h @@ -5,6 +5,7 @@ #include <stdint.h> #include <string.h> +#include <stdlib.h> #include <skalibs/buffer.h> #include <skalibs/strerr.h> @@ -45,6 +46,12 @@ struct global_s extern struct global_s g ; + /* util */ + +extern int keycmp (void const *, void const *) ; /* for any struct starting with a string key */ +#define BSEARCH(type, key, array) bsearch(key, (array), sizeof(array)/sizeof(type), sizeof(type), &keycmp) + + /* node */ extern void node_start (stralloc *, node *, char const *, size_t, uint32_t) ; @@ -68,17 +75,18 @@ extern void confnode_add (node *, char const *, size_t) ; extern node const *conftree_search (char const *) ; extern void conftree_add (node const *) ; extern void conftree_update (node const *) ; + extern int conftree_write (cdbmaker *) ; /* headers */ -extern void header_start (node *, char const *, size_t, uint32_t) ; -extern void header_add (node *, char const *, size_t) ; +extern void header_canonize (char *) ; +extern int header_allowed (char const *) ; extern node const *headers_search (char const *) ; -extern void headers_add (node const *) ; -extern int headers_write (void) ; +extern void headers_add (char const *, char const *, uint8_t, size_t, uint32_t) ; +extern void headers_finish (void) ; /* lexparse */ @@ -90,11 +98,4 @@ extern void conf_lexparse (buffer *, char const *) ; extern void conf_defaults (void) ; - - /* headers */ - -extern node const *headers_search (char const *) ; -extern void headers_add (node const *) ; -extern void headers_finish (void) ; - #endif diff --git a/src/config/util.c b/src/config/util.c new file mode 100644 index 0000000..bee1503 --- /dev/null +++ b/src/config/util.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <string.h> + +#include "tipidee-config-internal.h" + +struct starts_with_a_string_key_s +{ + char const *s ; +} ; + +int keycmp (void const *a, void const *b) +{ + return strcmp((char const *)a, ((struct starts_with_a_string_key_s const *)b)->s) ; +} |