]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
http: forbidden status / access_verify2() cleanups, fixes #5391
authorJaroslav Kysela <perex@perex.cz>
Mon, 3 Dec 2018 20:16:34 +0000 (21:16 +0100)
committerJaroslav Kysela <perex@perex.cz>
Mon, 3 Dec 2018 20:17:20 +0000 (21:17 +0100)
Return also forbidden status when the client is authenticated, but there
are not permissions for the requested operation.

src/access.h
src/http.c
src/http.h
src/webui/webui.c
src/webui/webui_api.c
src/webui/xmltv.c

index e413c5dbc02f1d6b3cb001af626d5234a73d4d19..9f84c7fdc7651f6a654594f55f39b914ac52df4e 100644 (file)
@@ -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);
 
index ab264d7a99af76c1aae4f076fb0f984b196615b3..13ec1d87dab46e670f038219a43aa7e64f6a5f53 100644 (file)
@@ -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;
     }
   }
index 40c36f1ccbb5a1eb0e29ac6cc499230d0f87e35e..c07773223cde4a0a0789bb175e1a794b05157868 100644 (file)
@@ -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);
index c09448aa7d853d7f981f43c0e3815efca8d04469..360216cce6428bf66151a044bb2bc837460011de 100644 (file)
@@ -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;
index 895214431f34c10025ac4ec89de25ee711835902..7bae1ea21781bf9a0471f8f2e1d0fa905bde6c5d 100644 (file)
@@ -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:
index 90668b6914b369bf6f306393f6c4418d154ebbeb..d7087c26cb3a8942b078ca10382c53bf36eb09c9 100644 (file)
@@ -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);