From 707b82b9c95519e9f3eb22f1e3d2a6cbe14f9b5c Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 21 Oct 2019 18:31:41 +0200 Subject: [PATCH] api: return EPERM for the empty arguments, fixes #5755 --- src/access.h | 4 ++++ src/api.c | 7 ++++++- src/api.h | 2 +- src/api/api_idnode.c | 16 +++++++++------- src/http.c | 7 ++++++- 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/access.h b/src/access.h index 4539a4645..4035d2584 100644 --- a/src/access.h +++ b/src/access.h @@ -227,6 +227,7 @@ typedef struct access_ticket { #define ACCESS_FAILED_RECORDER (1<<9) #define ACCESS_HTSP_ANONYMIZE (1<<10) #define ACCESS_ADMIN (1<<11) +#define ACCESS_NO_EMPTY_ARGS (1<<29) #define ACCESS_OR (1<<30) #define ACCESS_FULL \ @@ -236,6 +237,9 @@ typedef struct access_ticket { ACCESS_ALL_RECORDER | ACCESS_ALL_RW_RECORDER | \ ACCESS_FAILED_RECORDER | ACCESS_ADMIN) +#define ACCESS_INTERNAL \ + (ACCESS_NO_EMPTY_ARGS) + /** * Create a new ticket for the requested resource and generate a id for it */ diff --git a/src/api.c b/src/api.c index 868d48156..b224a30c5 100644 --- a/src/api.c +++ b/src/api.c @@ -67,6 +67,7 @@ api_exec ( access_t *perm, const char *subsystem, api_hook_t h; api_link_t *ah, skel; const char *op; + uint32_t access; /* Args and response must be set */ if (!args || !resp || !subsystem) @@ -84,7 +85,11 @@ api_exec ( access_t *perm, const char *subsystem, return ENOSYS; // TODO: is this really the right error code? } - if (access_verify2(perm, ah->hook->ah_access)) + access = ah->hook->ah_access; + if ((access & ACCESS_NO_EMPTY_ARGS) != 0 && htsmsg_is_empty(args)) + return EPERM; + + if (access_verify2(perm, access & ~ACCESS_INTERNAL)) return EPERM; /* Extract method */ diff --git a/src/api.h b/src/api.h index 7815e9617..a412776b9 100644 --- a/src/api.h +++ b/src/api.h @@ -38,7 +38,7 @@ typedef int (*api_callback_t) typedef struct api_hook { const char *ah_subsystem; - int ah_access; + uint32_t ah_access; api_callback_t ah_callback; void *ah_opaque; } api_hook_t; diff --git a/src/api/api_idnode.c b/src/api/api_idnode.c index fe0bf40a6..9096bfe9d 100644 --- a/src/api/api_idnode.c +++ b/src/api/api_idnode.c @@ -741,19 +741,21 @@ api_idnode_create_list( htsmsg_t **resp, htsmsg_t *list ) htsmsg_add_msg(*resp, "uuid", list); } +#define ACCESS_IDNODE (ACCESS_ANONYMOUS | ACCESS_NO_EMPTY_ARGS) + void api_idnode_init ( void ) { /* * note: permissions are verified using idnode_perm() calls */ static api_hook_t ah[] = { - { "idnode/load", ACCESS_ANONYMOUS, api_idnode_load, NULL }, - { "idnode/save", ACCESS_ANONYMOUS, api_idnode_save, NULL }, - { "idnode/tree", ACCESS_ANONYMOUS, api_idnode_tree, NULL }, - { "idnode/class", ACCESS_ANONYMOUS, api_idnode_class, NULL }, - { "idnode/delete", ACCESS_ANONYMOUS, api_idnode_delete, NULL }, - { "idnode/moveup", ACCESS_ANONYMOUS, api_idnode_moveup, NULL }, - { "idnode/movedown", ACCESS_ANONYMOUS, api_idnode_movedown, NULL }, + { "idnode/load", ACCESS_IDNODE, api_idnode_load, NULL }, + { "idnode/save", ACCESS_IDNODE, api_idnode_save, NULL }, + { "idnode/tree", ACCESS_IDNODE, api_idnode_tree, NULL }, + { "idnode/class", ACCESS_IDNODE, api_idnode_class, NULL }, + { "idnode/delete", ACCESS_IDNODE, api_idnode_delete, NULL }, + { "idnode/moveup", ACCESS_IDNODE, api_idnode_moveup, NULL }, + { "idnode/movedown", ACCESS_IDNODE, api_idnode_movedown, NULL }, { NULL }, }; diff --git a/src/http.c b/src/http.c index 698167f46..daabbccf0 100644 --- a/src/http.c +++ b/src/http.c @@ -1227,7 +1227,12 @@ http_exec(http_connection_t *hc, http_path_t *hp, char *remain) { int err; - if (http_access_verify(hc, hp->hp_accessmask)) { + /* this is a special case when client probably requires authentication */ + if ((hp->hp_accessmask & ACCESS_NO_EMPTY_ARGS) != 0 && TAILQ_EMPTY(&hc->hc_req_args)) { + err = http_noaccess_code(hc); + goto destroy; + } + if (http_access_verify(hc, hp->hp_accessmask & ~ACCESS_INTERNAL)) { if ((hp->hp_flags & HTTP_PATH_NO_VERIFICATION) == 0) { err = http_noaccess_code(hc); goto destroy; -- 2.47.2