From: Jaroslav Kysela Date: Mon, 3 Dec 2018 20:16:34 +0000 (+0100) Subject: http: forbidden status / access_verify2() cleanups, fixes #5391 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=da5dc10440572e4e6e93d000bff9c6ddc7cf0790;p=thirdparty%2Ftvheadend.git http: forbidden status / access_verify2() cleanups, fixes #5391 Return also forbidden status when the client is authenticated, but there are not permissions for the requested operation. --- diff --git a/src/access.h b/src/access.h index e413c5dbc..9f84c7fdc 100644 --- a/src/access.h +++ b/src/access.h @@ -263,9 +263,9 @@ access_get_theme(access_t *a); * Return 0 if access is granted, -1 otherwise */ static inline int access_verify2(const access_t *a, uint32_t mask) - { return (mask & ACCESS_OR) ? + { return a ? ((mask & ACCESS_OR) ? ((a->aa_rights & mask) ? 0 : -1) : - ((a->aa_rights & mask) == mask ? 0 : -1); } + ((a->aa_rights & mask) == mask ? 0 : -1)) : -1; } int access_verify_list(htsmsg_t *list, const char *item); diff --git a/src/http.c b/src/http.c index ab264d7a9..13ec1d87d 100644 --- a/src/http.c +++ b/src/http.c @@ -1129,10 +1129,20 @@ const char * http_username(http_connection_t *hc) { if (strempty(hc->hc_username) && hc->hc_access) - return hc->hc_access->aa_username; + return hc->hc_access->aa_username; return hc->hc_username; } +/** + * + */ +int +http_noaccess_code(http_connection_t *hc) +{ + return strempty(hc->hc_username) ? + HTTP_STATUS_UNAUTHORIZED : HTTP_STATUS_FORBIDDEN; +} + /** * */ @@ -1156,10 +1166,9 @@ http_exec(http_connection_t *hc, http_path_t *hp, char *remain) { int err; - if ((hc->hc_username && hc->hc_username[0] == '\0') || - http_access_verify(hc, hp->hp_accessmask)) { + if (http_access_verify(hc, hp->hp_accessmask)) { if ((hp->hp_flags & HTTP_PATH_NO_VERIFICATION) == 0) { - err = HTTP_STATUS_UNAUTHORIZED; + err = http_noaccess_code(hc); goto destroy; } } diff --git a/src/http.h b/src/http.h index 40c36f1cc..c07773223 100644 --- a/src/http.h +++ b/src/http.h @@ -217,6 +217,8 @@ int http_tokenize(char *buf, char **vec, int vecsize, int delimiter); const char * http_username(http_connection_t *hc); +int http_noaccess_code(http_connection_t *hc); + void http_alive(http_connection_t *hc); void http_error(http_connection_t *hc, int error); diff --git a/src/webui/webui.c b/src/webui/webui.c index c09448aa7..360216cce 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -153,7 +153,7 @@ page_login(http_connection_t *hc, const char *remain, void *opaque) http_redirect(hc, "/", &hc->hc_req_args, 0); return 0; } else { - return HTTP_STATUS_UNAUTHORIZED; + return http_noaccess_code(hc); } } @@ -622,7 +622,7 @@ http_channel_playlist(http_connection_t *hc, int pltype, int urlauth, channel_t char ubuf[UUID_HEX_SIZE]; if (http_access_verify_channel(hc, ACCESS_STREAMING, channel)) - return HTTP_STATUS_UNAUTHORIZED; + return http_noaccess_code(hc); profile = profile_validate_name(http_arg_get(&hc->hc_req_args, "profile")); hostpath = http_get_hostpath(hc); @@ -674,9 +674,8 @@ http_tag_playlist(http_connection_t *hc, int pltype, int urlauth, channel_tag_t channel_t **chlist; int idx, count = 0; - if(hc->hc_access == NULL || - access_verify2(hc->hc_access, ACCESS_STREAMING)) - return HTTP_STATUS_UNAUTHORIZED; + if (access_verify2(hc->hc_access, ACCESS_STREAMING)) + return http_noaccess_code(hc); lang = hc->hc_access->aa_lang_ui; hq = &hc->hc_reply; @@ -736,9 +735,8 @@ http_tag_list_playlist(http_connection_t *hc, int pltype, int urlauth) const char *blank, *sort, *lang; idnode_list_mapping_t *ilm; - if(hc->hc_access == NULL || - access_verify2(hc->hc_access, ACCESS_STREAMING)) - return HTTP_STATUS_UNAUTHORIZED; + if (access_verify2(hc->hc_access, ACCESS_STREAMING)) + return http_noaccess_code(hc); lang = hc->hc_access->aa_lang_ui; hq = &hc->hc_reply; @@ -806,9 +804,8 @@ http_channel_list_playlist(http_connection_t *hc, int pltype, int urlauth) char *profile, *hostpath; const char *name, *blank, *sort, *lang; - if(hc->hc_access == NULL || - access_verify2(hc->hc_access, ACCESS_STREAMING)) - return HTTP_STATUS_UNAUTHORIZED; + if (access_verify2(hc->hc_access, ACCESS_STREAMING)) + return http_noaccess_code(hc); hq = &hc->hc_reply; @@ -935,7 +932,7 @@ http_dvr_playlist(http_connection_t *hc, int pltype, int urlauth, dvr_entry_t *d return HTTP_STATUS_BAD_REQUEST; if(http_access_verify(hc, ACCESS_RECORDER)) - return HTTP_STATUS_UNAUTHORIZED; + return http_noaccess_code(hc); if(dvr_entry_verify(de, hc->hc_access, 1)) return HTTP_STATUS_NOT_FOUND; @@ -1113,7 +1110,7 @@ page_http_playlist_auth (http_connection_t *hc, const char *remain, void *opaque) { if (hc->hc_access == NULL || strempty(hc->hc_access->aa_auth)) - return HTTP_STATUS_UNAUTHORIZED; + return http_noaccess_code(hc); return page_http_playlist_(hc, remain, opaque, URLAUTH_CODE); } @@ -1135,7 +1132,7 @@ http_stream_service(http_connection_t *hc, service_t *service, int weight) int flags, eflags = 0; if(http_access_verify(hc, ACCESS_ADVANCED_STREAMING)) - return HTTP_STATUS_UNAUTHORIZED; + return http_noaccess_code(hc); if ((str = http_arg_get(&hc->hc_req_args, "descramble"))) if (strcmp(str, "0") == 0) @@ -1208,7 +1205,7 @@ http_stream_mux(http_connection_t *hc, mpegts_mux_t *mm, int weight) int res = HTTP_STATUS_SERVICE, i; if(http_access_verify(hc, ACCESS_ADVANCED_STREAMING)) - return HTTP_STATUS_UNAUTHORIZED; + return http_noaccess_code(hc); if((tcp_id = http_stream_preop(hc)) == NULL) return HTTP_STATUS_NOT_ALLOWED; @@ -1287,7 +1284,7 @@ http_stream_channel(http_connection_t *hc, channel_t *ch, int weight) int res = HTTP_STATUS_SERVICE; if (http_access_verify_channel(hc, ACCESS_STREAMING, ch)) - return HTTP_STATUS_UNAUTHORIZED; + return http_noaccess_code(hc); if(!(pro = profile_find_by_list(hc->hc_access->aa_profiles, http_arg_get(&hc->hc_req_args, "profile"), @@ -1567,12 +1564,11 @@ page_play_(http_connection_t *hc, const char *remain, void *opaque, int urlauth) if(remain == NULL) return HTTP_STATUS_NOT_FOUND; - if(hc->hc_access == NULL || - access_verify2(hc->hc_access, ACCESS_OR | + if(access_verify2(hc->hc_access, ACCESS_OR | ACCESS_STREAMING | ACCESS_ADVANCED_STREAMING | ACCESS_RECORDER)) - return HTTP_STATUS_UNAUTHORIZED; + return http_noaccess_code(hc); playlist = http_arg_get(&hc->hc_req_args, "playlist"); if (playlist) { @@ -1602,7 +1598,7 @@ static int page_play_auth(http_connection_t *hc, const char *remain, void *opaque) { if (hc->hc_access == NULL || strempty(hc->hc_access->aa_auth)) - return HTTP_STATUS_UNAUTHORIZED; + return http_noaccess_code(hc); return page_play_(hc, remain, opaque, URLAUTH_CODE); } @@ -1642,7 +1638,7 @@ page_srvid2(http_connection_t *hc, const char *remain, void *opaque) char buf1[16], buf2[16], buf3[16]; if (hc->hc_access == NULL || strempty(hc->hc_access->aa_auth)) - return HTTP_STATUS_UNAUTHORIZED; + return http_noaccess_code(hc); tvh_mutex_lock(&global_lock); TAILQ_FOREACH(t, &service_all, s_all_link) { if (!idnode_is_instance(&t->s_id, &mpegts_service_class)) @@ -1928,12 +1924,11 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque) if(remain == NULL) return HTTP_STATUS_BAD_REQUEST; - if(hc->hc_access == NULL || - (access_verify2(hc->hc_access, ACCESS_OR | - ACCESS_STREAMING | - ACCESS_ADVANCED_STREAMING | - ACCESS_RECORDER))) - return HTTP_STATUS_UNAUTHORIZED; + if(access_verify2(hc->hc_access, ACCESS_OR | + ACCESS_STREAMING | + ACCESS_ADVANCED_STREAMING | + ACCESS_RECORDER)) + return http_noaccess_code(hc); tvh_mutex_lock(&global_lock); de = dvr_entry_find_by_uuid(remain); @@ -1945,7 +1940,7 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque) } if(dvr_entry_verify(de, hc->hc_access, 1)) { tvh_mutex_unlock(&global_lock); - return HTTP_STATUS_UNAUTHORIZED; + return http_noaccess_code(hc); } priv.uuid = remain; @@ -1984,15 +1979,14 @@ page_imagecache(http_connection_t *hc, const char *remain, void *opaque) if(remain == NULL) return HTTP_STATUS_NOT_FOUND; - if(hc->hc_access == NULL || - (access_verify2(hc->hc_access, ACCESS_OR | - ACCESS_WEB_INTERFACE | - ACCESS_STREAMING | - ACCESS_ADVANCED_STREAMING | - ACCESS_HTSP_STREAMING | - ACCESS_HTSP_RECORDER | - ACCESS_RECORDER))) - return HTTP_STATUS_UNAUTHORIZED; + if(access_verify2(hc->hc_access, ACCESS_OR | + ACCESS_WEB_INTERFACE | + ACCESS_STREAMING | + ACCESS_ADVANCED_STREAMING | + ACCESS_HTSP_STREAMING | + ACCESS_HTSP_RECORDER | + ACCESS_RECORDER)) + return http_noaccess_code(hc); if(sscanf(remain, "%d", &id) != 1) return HTTP_STATUS_BAD_REQUEST; diff --git a/src/webui/webui_api.c b/src/webui/webui_api.c index 895214431..7bae1ea21 100644 --- a/src/webui/webui_api.c +++ b/src/webui/webui_api.c @@ -48,7 +48,7 @@ webui_api_handler switch (r) { case EPERM: case EACCES: - r = HTTP_STATUS_UNAUTHORIZED; + r = http_noaccess_code(hc); break; case ENOENT: case ENOSYS: diff --git a/src/webui/xmltv.c b/src/webui/xmltv.c index 90668b691..d7087c26c 100644 --- a/src/webui/xmltv.c +++ b/src/webui/xmltv.c @@ -214,7 +214,7 @@ http_xmltv_channel(http_connection_t *hc, channel_t *channel) char *hostpath; if (http_access_verify_channel(hc, ACCESS_STREAMING, channel)) - return HTTP_STATUS_UNAUTHORIZED; + return http_noaccess_code(hc); hostpath = http_get_hostpath(hc); http_xmltv_begin(&hc->hc_reply); @@ -236,9 +236,8 @@ http_xmltv_tag(http_connection_t *hc, channel_tag_t *tag) char *hostpath; channel_t *ch; - if (hc->hc_access == NULL || - access_verify2(hc->hc_access, ACCESS_STREAMING)) - return HTTP_STATUS_UNAUTHORIZED; + if (access_verify2(hc->hc_access, ACCESS_STREAMING)) + return http_noaccess_code(hc); hostpath = http_get_hostpath(hc); @@ -270,9 +269,8 @@ http_xmltv_channel_list(http_connection_t *hc) channel_t *ch; char *hostpath; - if (hc->hc_access == NULL || - access_verify2(hc->hc_access, ACCESS_STREAMING)) - return HTTP_STATUS_UNAUTHORIZED; + if (access_verify2(hc->hc_access, ACCESS_STREAMING)) + return http_noaccess_code(hc); hostpath = http_get_hostpath(hc);