]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
ACL: add more restrictive permissions for all config urls, fix the http ticket issue...
authorJaroslav Kysela <perex@perex.cz>
Thu, 16 Oct 2014 09:03:22 +0000 (11:03 +0200)
committerJaroslav Kysela <perex@perex.cz>
Thu, 16 Oct 2014 09:03:22 +0000 (11:03 +0200)
20 files changed:
src/access.c
src/api/api_access.c
src/api/api_mpegts.c
src/api/api_service.c
src/esfilter.c
src/http.c
src/http.h
src/idnode.c
src/idnode.h
src/input/mpegts/mpegts_input.c
src/input/mpegts/mpegts_mux.c
src/input/mpegts/mpegts_network.c
src/main.c
src/profile.c
src/service.c
src/webui/static/app/acleditor.js
src/webui/static/app/caclient.js
src/webui/static/app/esfilter.js
src/webui/static/app/mpegts.js
src/webui/static/app/tvheadend.js

index 27f6dec865d02f8e15c1b05122d89551dad2c512..7fc9ae9cef8330f25246dac0f00b2c58fbfab04f 100644 (file)
@@ -1030,6 +1030,7 @@ const idclass_t access_entry_class = {
   .ic_class      = "access",
   .ic_caption    = "Access",
   .ic_event      = "access",
+  .ic_perm_def   = ACCESS_ADMIN,
   .ic_save       = access_entry_class_save,
   .ic_get_title  = access_entry_class_get_title,
   .ic_delete     = access_entry_class_delete,
index 15d87214ab8f58537cb3286992bf3fe1952ed2b1..63f98398fb12f3c8a561fbc19e8aa8a7d7d25e00 100644 (file)
@@ -52,9 +52,9 @@ api_access_entry_create
 void api_access_init ( void )
 {
   static api_hook_t ah[] = {
-    { "access/entry/class",    ACCESS_ANONYMOUS, api_idnode_class, (void*)&access_entry_class },
-    { "access/entry/grid",     ACCESS_ANONYMOUS, api_idnode_grid,  api_access_entry_grid },
-    { "access/entry/create",   ACCESS_ADMIN,     api_access_entry_create, NULL },
+    { "access/entry/class",  ACCESS_ADMIN, api_idnode_class, (void*)&access_entry_class },
+    { "access/entry/grid",   ACCESS_ADMIN, api_idnode_grid,  api_access_entry_grid },
+    { "access/entry/create", ACCESS_ADMIN, api_access_entry_create, NULL },
 
     { NULL },
   };
index 618ae6832e653888bbf7bca590eafd9a4d5b9080..30e8a01789e1145eb3a02fe5fdcd860bb837086b 100644 (file)
@@ -347,22 +347,22 @@ api_mpegts_init ( void )
   extern const idclass_t mpegts_service_class;
 
   static api_hook_t ah[] = {
-    { "mpegts/input/network_list", ACCESS_ANONYMOUS, api_mpegts_input_network_list, NULL },
-    { "mpegts/network/grid",       ACCESS_ANONYMOUS, api_idnode_grid,  api_mpegts_network_grid },
-    { "mpegts/network/class",      ACCESS_ANONYMOUS, api_idnode_class, (void*)&mpegts_network_class },
-    { "mpegts/network/builders",   ACCESS_ANONYMOUS, api_mpegts_network_builders, NULL },
-    { "mpegts/network/create",     ACCESS_ANONYMOUS, api_mpegts_network_create,   NULL },
-    { "mpegts/network/mux_class",  ACCESS_ANONYMOUS, api_mpegts_network_muxclass, NULL },
-    { "mpegts/network/mux_create", ACCESS_ANONYMOUS, api_mpegts_network_muxcreate, NULL },
-    { "mpegts/mux/grid",           ACCESS_ANONYMOUS, api_idnode_grid,  api_mpegts_mux_grid },
-    { "mpegts/mux/class",          ACCESS_ANONYMOUS, api_idnode_class, (void*)&mpegts_mux_class },
-    { "mpegts/service/grid",       ACCESS_ANONYMOUS, api_idnode_grid,  api_mpegts_service_grid },
-    { "mpegts/service/class",      ACCESS_ANONYMOUS, api_idnode_class, (void*)&mpegts_service_class },
-    { "mpegts/mux_sched/class",    ACCESS_ANONYMOUS, api_idnode_class, (void*)&mpegts_mux_sched_class },
-    { "mpegts/mux_sched/grid",     ACCESS_ANONYMOUS, api_idnode_grid, api_mpegts_mux_sched_grid },
-    { "mpegts/mux_sched/create",   ACCESS_ANONYMOUS, api_mpegts_mux_sched_create, NULL },
+    { "mpegts/input/network_list", ACCESS_ADMIN, api_mpegts_input_network_list, NULL },
+    { "mpegts/network/grid",       ACCESS_ADMIN, api_idnode_grid,  api_mpegts_network_grid },
+    { "mpegts/network/class",      ACCESS_ADMIN, api_idnode_class, (void*)&mpegts_network_class },
+    { "mpegts/network/builders",   ACCESS_ADMIN, api_mpegts_network_builders, NULL },
+    { "mpegts/network/create",     ACCESS_ADMIN, api_mpegts_network_create,   NULL },
+    { "mpegts/network/mux_class",  ACCESS_ADMIN, api_mpegts_network_muxclass, NULL },
+    { "mpegts/network/mux_create", ACCESS_ADMIN, api_mpegts_network_muxcreate, NULL },
+    { "mpegts/mux/grid",           ACCESS_ADMIN, api_idnode_grid,  api_mpegts_mux_grid },
+    { "mpegts/mux/class",          ACCESS_ADMIN, api_idnode_class, (void*)&mpegts_mux_class },
+    { "mpegts/service/grid",       ACCESS_ADMIN, api_idnode_grid,  api_mpegts_service_grid },
+    { "mpegts/service/class",      ACCESS_ADMIN, api_idnode_class, (void*)&mpegts_service_class },
+    { "mpegts/mux_sched/class",    ACCESS_ADMIN, api_idnode_class, (void*)&mpegts_mux_sched_class },
+    { "mpegts/mux_sched/grid",     ACCESS_ADMIN, api_idnode_grid, api_mpegts_mux_sched_grid },
+    { "mpegts/mux_sched/create",   ACCESS_ADMIN, api_mpegts_mux_sched_create, NULL },
 #if ENABLE_MPEGTS_DVB
-    { "dvb/scanfile/list",         ACCESS_ANONYMOUS, api_dvb_scanfile_list, NULL },
+    { "dvb/scanfile/list",         ACCESS_ADMIN, api_dvb_scanfile_list, NULL },
 #endif
     { NULL },
   };
index 3cc822eaabc46535413d19c8ba4a5ac9f972532f..38012e4297098b2488da6be7883560bdfc2a4270 100644 (file)
@@ -189,9 +189,9 @@ void api_service_init ( void )
     { "service/mapper/start",   ACCESS_ADMIN, api_mapper_start,  NULL },
     { "service/mapper/stop",    ACCESS_ADMIN, api_mapper_stop,   NULL },
     { "service/mapper/status",  ACCESS_ADMIN, api_mapper_status, NULL },
-    { "service/list",           ACCESS_ANONYMOUS, api_idnode_load_by_class, 
+    { "service/list",           ACCESS_ADMIN, api_idnode_load_by_class,
       (void*)&service_class },
-    { "service/streams",        ACCESS_ANONYMOUS, api_service_streams, NULL },
+    { "service/streams",        ACCESS_ADMIN, api_service_streams, NULL },
     { NULL },
   };
 
index 0f72938b3313536a5b01f28979defb6782d23d17..802e0e5d26db8a88300f956948ebec66dfe77cc4 100644 (file)
@@ -20,6 +20,7 @@
 #include "settings.h"
 #include "lang_codes.h"
 #include "service.h"
+#include "access.h"
 #include "esfilter.h"
 
 struct esfilter_entry_queue esfilters[ESF_CLASS_LAST + 1];
@@ -588,6 +589,7 @@ const idclass_t esfilter_class = {
   .ic_class      = "esfilter",
   .ic_caption    = "Elementary Stream Filter",
   .ic_event      = "esfilter",
+  .ic_perm_def   = ACCESS_ADMIN,
   .ic_save       = esfilter_class_save,
   .ic_get_title  = esfilter_class_get_title,
   .ic_delete     = esfilter_class_delete,
index 1959b9dc9575765cd0718f9114c60da9c64199f0..1f42111b475937ec3a21dd7a572bb0b7612c062b 100644 (file)
@@ -408,22 +408,21 @@ http_redirect(http_connection_t *hc, const char *location,
 /**
  *
  */
-static int http_access_verify_ticket(http_connection_t *hc)
+static void
+http_access_verify_ticket(http_connection_t *hc)
 {
   const char *ticket_id;
 
-  if (hc->hc_ticket || hc->hc_access)
-    return 0;
+  if (hc->hc_access)
+    return;
   ticket_id = http_arg_get(&hc->hc_req_args, "ticket");
   hc->hc_access = access_ticket_verify2(ticket_id, hc->hc_url);
   if (hc->hc_access == NULL)
-    return -1;
+    return;
   char addrstr[50];
   tcp_get_ip_str((struct sockaddr*)hc->hc_peer, addrstr, 50);
   tvhlog(LOG_INFO, "HTTP", "%s: using ticket %s for %s",
         addrstr, ticket_id, hc->hc_url);
-  hc->hc_ticket = 1;
-  return 0;
 }
 
 /**
@@ -432,8 +431,7 @@ static int http_access_verify_ticket(http_connection_t *hc)
 int
 http_access_verify(http_connection_t *hc, int mask)
 {
-  if (!http_access_verify_ticket(hc))
-    return 0;
+  http_access_verify_ticket(hc);
 
   if (hc->hc_access == NULL) {
     hc->hc_access = access_get(hc->hc_username, hc->hc_password,
@@ -456,8 +454,8 @@ http_access_verify_channel(http_connection_t *hc, int mask,
 
   assert(ch);
 
-  if (ticket && !http_access_verify_ticket(hc))
-    return 0;
+  if (ticket)
+    http_access_verify_ticket(hc);
 
   if (hc->hc_access == NULL) {
     hc->hc_access = access_get(hc->hc_username, hc->hc_password,
@@ -488,7 +486,6 @@ http_exec(http_connection_t *hc, http_path_t *hp, char *remain)
     err = hp->hp_callback(hc, remain, hp->hp_opaque);
   access_destroy(hc->hc_access);
   hc->hc_access = NULL;
-  hc->hc_ticket = 0;
 
   if(err == -1)
      return 1;
index 544db669e562895674fec3484a751e72a60e28bc..010ea6a9914843a5e6f8bedb0b32943b48de81d7 100644 (file)
@@ -132,7 +132,6 @@ typedef struct http_connection {
   char *hc_username;
   char *hc_password;
   access_t *hc_access;
-  int hc_ticket;
 
   struct config_head *hc_user_config;
 
index 33a15d3c8ffb2346f73c39f50e8e53093e93350c..962d0ba196aad1faa88d975889e3bc50f7cffd79 100644 (file)
@@ -29,6 +29,7 @@
 #include "notify.h"
 #include "settings.h"
 #include "uuid.h"
+#include "access.h"
 
 static const idnodes_rb_t * idnode_domain ( const idclass_t *idc );
 static void idclass_root_register ( idnode_t *in );
@@ -548,6 +549,21 @@ idnode_get_time
  * Lookup
  * *************************************************************************/
 
+int
+idnode_perm(idnode_t *self, struct access *a, htsmsg_t *msg_to_write)
+{
+  const idclass_t *ic = self->in_class;
+
+  while (ic) {
+    if (ic->ic_perm)
+      return self->in_class->ic_perm(self, a, msg_to_write);
+    if (ic->ic_perm_def)
+      return access_verify2(a, self->in_class->ic_perm_def);
+    ic = ic->ic_super;
+  }
+  return 0;
+}
+
 /**
  *
  */
index 12693533b945e0b3d6c278d5aa89f3fc5632edf2..fbaae48f448fcaae228e48de7929843e18ab1e81 100644 (file)
@@ -62,6 +62,7 @@ struct idclass {
   const property_group_t *ic_groups;       ///< Groups for visual representation
   const property_t       *ic_properties;   ///< Property list
   const char             *ic_event;        ///< Events to fire on add/delete/title
+  uint32_t                ic_perm_def;     ///< Default permissions
 
   /* Callbacks */
   idnode_set_t   *(*ic_get_childs) (idnode_t *self);
@@ -175,13 +176,7 @@ int       idnode_write0 (idnode_t *self, htsmsg_t *m, int optmask, int dosave);
 #define idnode_save(in, m)     idnode_read0(in, m, NULL, PO_NOSAVE | PO_USERAW)
 #define idnode_update(in, m)   idnode_write0(in, m, PO_RDONLY | PO_WRONCE, 1)
 
-static inline int
-idnode_perm(idnode_t *self, struct access *a, htsmsg_t *msg_to_write)
-{
-  if (self->in_class->ic_perm)
-    return self->in_class->ic_perm(self, a, msg_to_write);
-  return 0;
-}
+int idnode_perm(idnode_t *self, struct access *a, htsmsg_t *msg_to_write);
 
 const char *idnode_get_str (idnode_t *self, const char *key );
 int         idnode_get_u32 (idnode_t *self, const char *key, uint32_t *u32);
index 35e9a9ba4d2b52db3e404346c2095dc0d02ca506..c6ef152e2abb2574b368d6f7ae9fe25e18109e47 100644 (file)
@@ -21,6 +21,7 @@
 #include "packet.h"
 #include "streaming.h"
 #include "subscriptions.h"
+#include "access.h"
 #include "atomic.h"
 #include "notify.h"
 #include "idnode.h"
@@ -143,6 +144,7 @@ const idclass_t mpegts_input_class =
   .ic_class      = "mpegts_input",
   .ic_caption    = "MPEGTS Input",
   .ic_event      = "mpegts_input",
+  .ic_perm_def   = ACCESS_ADMIN,
   .ic_get_title  = mpegts_input_class_get_title,
   .ic_properties = (const property_t[]){
     {
index 1a9fc9f9fcf29c44d38279a7c06a4396d680ed26..30271c1e3a8d32e7937129fb1b1a2d87abb87d50 100644 (file)
@@ -21,6 +21,7 @@
 #include "queue.h"
 #include "input.h"
 #include "subscriptions.h"
+#include "access.h"
 #include "dvb_charset.h"
 
 #include <assert.h>
@@ -37,6 +38,7 @@ const idclass_t mpegts_mux_instance_class =
 {
   .ic_class      = "mpegts_mux_instance",
   .ic_caption    = "MPEGTS Multiplex Phy",
+  .ic_perm_def   = ACCESS_ADMIN
 };
 
 static void
@@ -319,6 +321,7 @@ const idclass_t mpegts_mux_class =
   .ic_class      = "mpegts_mux",
   .ic_caption    = "MPEGTS Multiplex",
   .ic_event      = "mpegts_mux",
+  .ic_perm_def   = ACCESS_ADMIN,
   .ic_save       = mpegts_mux_class_save,
   .ic_delete     = mpegts_mux_class_delete,
   .ic_get_title  = mpegts_mux_class_get_title,
index d7f8561c625e447d880fddeb77ec071a3d0ebf0f..a07dea02d77a76548dd627d8627289327457c95b 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "input.h"
 #include "subscriptions.h"
+#include "access.h"
 #include "dvb_charset.h"
 
 #include <assert.h>
@@ -109,8 +110,9 @@ const idclass_t mpegts_network_class =
 {
   .ic_class      = "mpegts_network",
   .ic_caption    = "MPEGTS Network",
-  .ic_save       = mpegts_network_class_save,
   .ic_event      = "mpegts_network",
+  .ic_perm_def   = ACCESS_ADMIN,
+  .ic_save       = mpegts_network_class_save,
   .ic_get_title  = mpegts_network_class_get_title,
   .ic_properties = (const property_t[]){
     {
index 3322b37dc849cfc138b282b53b337048c3a1461c..f4eeb4c11a556766854c45601435a9781114b067 100644 (file)
@@ -137,17 +137,8 @@ const tvh_caps_t tvheadend_capabilities[] = {
 #if ENABLE_CWC || ENABLE_CAPMT || ENABLE_CONSTCW
   { "caclient", NULL },
 #endif
-#if ENABLE_V4L
-  { "v4l", NULL },
-#endif
-#if ENABLE_LINUXDVB
-  { "linuxdvb", NULL },
-#endif
-#if ENABLE_SATIP_CLIENT
-  { "satip_client", NULL },
-#endif
-#if ENABLE_HDHOMERUN_CLIENT
-  { "tvhdhomerun_client", NULL },
+#if ENABLE_V4L || ENABLE_LINUXDVB || ENABLE_SATIP_CLIENT || ENABLE_HDHOMERUN_CLIENT
+  { "tvadapters", NULL },
 #endif
 #if ENABLE_IMAGECACHE
   { "imagecache", (uint32_t*)&imagecache_conf.enabled },
index 5752d1c356f0adbeb5cfa03c80b03410b4e05b8a..51cc0459f3b9f3d04c198a4b7643f4d860568ca1 100644 (file)
@@ -20,6 +20,7 @@
 #include "settings.h"
 #include "profile.h"
 #include "streaming.h"
+#include "access.h"
 #include "plumbing/tsfix.h"
 #include "plumbing/globalheaders.h"
 #if ENABLE_LIBAV
@@ -218,8 +219,9 @@ const idclass_t profile_class =
 {
   .ic_class      = "profile",
   .ic_caption    = "Stream Profile",
-  .ic_save       = profile_class_save,
   .ic_event      = "profile",
+  .ic_perm_def   = ACCESS_ADMIN,
+  .ic_save       = profile_class_save,
   .ic_get_title  = profile_class_get_title,
   .ic_delete     = profile_class_delete,
   .ic_properties = (const property_t[]){
index 9157b59519ea96bce7e2bc40c6f1c92417f4f4d5..9622bcd3825fd4ddd3d1f9cc11e07025dfba7c14 100644 (file)
@@ -44,6 +44,7 @@
 #include "lang_codes.h"
 #include "descrambler.h"
 #include "input.h"
+#include "access.h"
 #include "esfilter.h"
 
 static void service_data_timeout(void *aux);
@@ -169,6 +170,7 @@ const idclass_t service_class = {
   .ic_class      = "service",
   .ic_caption    = "Service",
   .ic_event      = "service",
+  .ic_perm_def   = ACCESS_ADMIN,
   .ic_save       = service_class_save,
   .ic_get_title  = service_class_get_title,
   .ic_properties = (const property_t[]){
index 97d805ad1e0765653e543233b8bf0e140036839b..dc68e13621ea727fc30acda9822b634af383bd93 100644 (file)
@@ -14,7 +14,7 @@ tvheadend.acleditor = function(panel, index)
         titleP: 'Access Entries',
         iconCls: 'group',
         columns: {
-                       enabled:       { width: 120 },
+            enabled:       { width: 120 },
             username:      { width: 250 },
             password:      { width: 250 },
             prefix:        { width: 350 },
index 40e00a930a0bccf80c82c6877666ba2222056bee..f605e91c02d95a22995f42e75c383cb1a6bf81f5 100644 (file)
@@ -2,15 +2,18 @@
  * Conditional Access Client (cwc,capmt)
  */
 
-tvheadend.caclient_builders = new Ext.data.JsonStore({
-    url: 'api/caclient/builders',
-    root: 'entries',
-    fields: ['class', 'caption', 'props'],
-    id: 'class',
-    autoLoad: true
-});
-
 tvheadend.caclient = function(panel, index) {
+
+    if (!tvheadend.caclient_builders) {
+        tvheadend.caclient_builders = new Ext.data.JsonStore({
+            url: 'api/caclient/builders',
+            root: 'entries',
+            fields: ['class', 'caption', 'props'],
+            id: 'class',
+            autoLoad: true
+        });
+    }
+
     var actions = new Ext.ux.grid.RowActions({
         id: 'status',
         header: '',
index b89e89e25d50b2dac7ac644fd947fe7c37de131a..68e770455f04e99a453572c4b57e9da8e7661c22 100644 (file)
@@ -2,16 +2,18 @@
  * Stream Profiles, Elementary Stream Filters
  */
 
-tvheadend.profile_builders = new Ext.data.JsonStore({
-    url: 'api/profile/builders',
-    root: 'entries',
-    fields: ['class', 'caption', 'props'],
-    id: 'class',
-    autoLoad: true
-});                    
-
 tvheadend.esfilter_tab = function(panel)
 {
+    if (!tvheadend.profile_builders) {
+        tvheadend.profile_builders = new Ext.data.JsonStore({
+            url: 'api/profile/builders',
+            root: 'entries',
+            fields: ['class', 'caption', 'props'],
+            id: 'class',
+            autoLoad: true
+        });
+    }
+
     var list = '-class';
 
     tvheadend.idnode_form_grid(panel, {
index b92eb4e8ee8daa663ca7e1b20d3c43f7f99ee4c2..cdbc25743fab83a9664837074462f7890d63d869 100644 (file)
@@ -2,31 +2,31 @@
  * DVB network
  */
 
-tvheadend.network_builders = new Ext.data.JsonStore({
-    url: 'api/mpegts/network/builders',
-    root: 'entries',
-    fields: ['class', 'caption', 'props'],
-    id: 'class',
-    autoLoad: true
-});
-
-tvheadend.network_list = new Ext.data.JsonStore({
-    url: 'api/idnode/load',
-    baseParams: {class: 'mpegts_network', enum: 1},
-    root: 'entries',
-    fields: ['key', 'val'],
-    id: 'key',
-    autoLoad: true
-});
-
-tvheadend.comet.on('mpegts_network', function() {
-    // TODO: Might be a bit excessive
-    tvheadend.network_builders.reload();
-    tvheadend.network_list.reload();
-});
-
 tvheadend.networks = function(panel, index)
 {
+    if (!tvheadend.network_list) {
+        tvheadend.network_list = new Ext.data.JsonStore({
+            url: 'api/idnode/load',
+            baseParams: {class: 'mpegts_network', enum: 1},
+            root: 'entries',
+            fields: ['key', 'val'],
+            id: 'key',
+            autoLoad: true
+        });
+        tvheadend.network_builders = new Ext.data.JsonStore({
+            url: 'api/mpegts/network/builders',
+            root: 'entries',
+            fields: ['class', 'caption', 'props'],
+            id: 'class',
+            autoLoad: true
+        });
+        tvheadend.comet.on('mpegts_network', function() {
+            // TODO: Might be a bit excessive
+            tvheadend.network_builders.reload();
+            tvheadend.network_list.reload();
+        });
+    }
+
     tvheadend.idnode_grid(panel, {
         url: 'api/mpegts/network',
         titleS: 'Network',
index cb73ef174c174987fc087ee7c2e9fe9fd8b97675..0be16ed7faba159a75ed23d4abf66201fa711ecb 100644 (file)
@@ -1,8 +1,6 @@
 tvheadend.dynamic = true;
 tvheadend.accessupdate = null;
-tvheadend.capabilties = null;
-tvheadend.dvrpanel = null;
-tvheadend.confpanel = null;
+tvheadend.capabilities = null;
 
 /* State Provider */
 Ext.state.Manager.setProvider(new Ext.state.CookieProvider({
@@ -353,9 +351,7 @@ function accessUpdate(o) {
 
         var idx = 0;
 
-        if (tvheadend.capabilities.indexOf('linuxdvb')     !== -1 ||
-            tvheadend.capabilities.indexOf('satip_client') !== -1 ||
-            tvheadend.capabilities.indexOf('v4l')          !== -1)
+        if (tvheadend.capabilities.indexOf('tvadapters') !== -1)
             tvheadend.tvadapters(dvbin);
         tvheadend.networks(dvbin);
         tvheadend.muxes(dvbin);