]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Enable HTSP by default and bring it up to speed with rest of
authorAndreas Öman <andreas@lonelycoder.com>
Sat, 17 May 2008 16:48:34 +0000 (16:48 +0000)
committerAndreas Öman <andreas@lonelycoder.com>
Sat, 17 May 2008 16:48:34 +0000 (16:48 +0000)
access-control framework

htsp.c
main.c
rpc.c
rpc.h

diff --git a/htsp.c b/htsp.c
index 64688cd232b5b14a4958420f0566c9d5c77daadd..b49320c1fd034876fcf2340856e058d683aa5155 100644 (file)
--- a/htsp.c
+++ b/htsp.c
@@ -165,7 +165,8 @@ htsp_input(htsp_t *htsp, const void *buf, int len)
   printf("INPUT:\n");
   htsmsg_print(in);
 
-  out = rpc_dispatch(&htsp->htsp_rpc, in, NULL, htsp);
+  out = rpc_dispatch(&htsp->htsp_rpc, in, NULL, htsp,
+                    (struct sockaddr *)&htsp->htsp_tcp_session.tcp_peer_addr);
 
   htsmsg_destroy(in);
 
@@ -175,6 +176,7 @@ htsp_input(htsp_t *htsp, const void *buf, int len)
   htsp_send_msg(htsp, out, 0);
 
   if(!was_async && htsp->htsp_rpc.rs_is_async) {
+    printf("Session went into async mode\n");
     /* Session went into async state */
     htsp_send_all_channels(htsp);
   }
diff --git a/main.c b/main.c
index 47ca34182d70a75534e72788b66f91f56c4e0e39..d595451cfd3b7e5b793f8e75ae80075427778010 100644 (file)
--- a/main.c
+++ b/main.c
@@ -277,7 +277,7 @@ main(int argc, char **argv)
       if(p)
        http_start(p);
 
-      p = atoi(config_get_str("htsp-server-port", "0"));
+      p = atoi(config_get_str("htsp-server-port", "9910"));
       if(p)
        htsp_start(p);
 
diff --git a/rpc.c b/rpc.c
index 4902e3c8b4bd52b12cdda20c6f7efe0a27d5b637..27c19647126b30053c980ac6484ec038c1da0940 100644 (file)
--- a/rpc.c
+++ b/rpc.c
@@ -37,6 +37,7 @@
 #include "epg.h"
 #include "pvr.h"
 #include "rpc.h"
+#include "access.h"
 
 
 /** 
@@ -89,33 +90,50 @@ rpc_error(rpc_session_t *ses, const char *err)
 
 
 
+/** 
+ * Simple function to respond with an error
+ */
+htsmsg_t *
+rpc_unauthorized(rpc_session_t *ses)
+{
+  htsmsg_t *r = htsmsg_create();
+  htsmsg_add_u32(r, "seq", ses->rs_seq);
+  htsmsg_add_u32(r, "_noaccess", 1);
+  return r;
+}
+
+
+
+
 /**
- * Login peer, set auth level and do various other stuff
+ * Auth peer
  */
 static htsmsg_t *
-rpc_login(rpc_session_t *ses, htsmsg_t *in, void *opaque)
+rpc_auth(rpc_session_t *ses, htsmsg_t *in, void *opaque)
 {
   const char *user = htsmsg_get_str(in, "username");
   const char *pass = htsmsg_get_str(in, "password");
 
-  if(user == NULL || pass == NULL) {
-    ses->rs_authlevel = 1;
-    ses->rs_maxweight = 100;
-  } else {
-    /* FIXME: user/password database */
-    ses->rs_authlevel = 1;
-  }
+  if(user != NULL && pass != NULL) {
+    free(ses->rs_username);
+    free(ses->rs_password);
 
-  if(htsmsg_get_u32(in, "async", &ses->rs_is_async) < 0)
-    ses->rs_is_async = 0;
+    ses->rs_username = strdup(user);
+    ses->rs_password = strdup(pass);
+  }
 
   return rpc_ok(ses);
 }
 
-
-
-
-
+/**
+ * Set client in async mode
+ */
+static htsmsg_t *
+rpc_async(rpc_session_t *ses, htsmsg_t *in, void *opaque)
+{
+  ses->rs_is_async = 1;
+  return rpc_ok(ses);
+}
 
 
 /*
@@ -327,9 +345,10 @@ htsp_subscribe(htsp_connection_t *hc, htsp_msg_t *m)
  */
 
 static rpc_cmd_t common_rpc[] = {
-  { "login",        rpc_login,         0 },
-  { "channelsList", rpc_channels_list, 1 },
-  { "eventInfo",    rpc_event_info,    1 },
+  { "auth",         rpc_auth,          0 },
+  { "async",        rpc_async,         ACCESS_STREAMING },
+  { "channelsList", rpc_channels_list, ACCESS_STREAMING },
+  { "eventInfo",    rpc_event_info,    ACCESS_STREAMING },
 #if 0
   { "subscribe",    rpc_subscribe,     1 },
   { "unsubscribe",  rpc_unsubscribe,   1 },
@@ -344,13 +363,14 @@ static rpc_cmd_t common_rpc[] = {
  */
 static htsmsg_t *
 rpc_dispatch_set(rpc_session_t *ses, htsmsg_t *in, rpc_cmd_t *cmds,
-                void *opaque, const char *method)
+                void *opaque, const char *method, struct sockaddr *peer)
 {
   for(; cmds->rc_name; cmds++) {
     if(strcmp(cmds->rc_name, method))
       continue;
-    if(cmds->rc_authlevel < ses->rs_authlevel)
-      return rpc_error(ses, "Insufficient privileges");
+    if(access_verify(ses->rs_username, ses->rs_password, peer, 
+                    cmds->rc_privmask))
+      return rpc_unauthorized(ses);
     return cmds->rc_func(ses, in, opaque);
   }
   return NULL;
@@ -361,7 +381,8 @@ rpc_dispatch_set(rpc_session_t *ses, htsmsg_t *in, rpc_cmd_t *cmds,
  *
  */
 htsmsg_t *
-rpc_dispatch(rpc_session_t *ses, htsmsg_t *in, rpc_cmd_t *cmds, void *opaque)
+rpc_dispatch(rpc_session_t *ses, htsmsg_t *in, rpc_cmd_t *cmds, void *opaque,
+            struct sockaddr *peer)
 {
   const char *method;
   htsmsg_t *out;
@@ -372,9 +393,9 @@ rpc_dispatch(rpc_session_t *ses, htsmsg_t *in, rpc_cmd_t *cmds, void *opaque)
   if((method = htsmsg_get_str(in, "method")) == NULL)
     return rpc_error(ses, "Method not specified");
 
-  out = rpc_dispatch_set(ses, in, common_rpc, opaque, method);
+  out = rpc_dispatch_set(ses, in, common_rpc, opaque, method, peer);
   if(out == NULL && cmds != NULL) 
-    out = rpc_dispatch_set(ses, in, cmds, opaque, method);
+    out = rpc_dispatch_set(ses, in, cmds, opaque, method, peer);
 
   return out ?: rpc_error(ses, "Method not found");
 }
@@ -396,5 +417,8 @@ rpc_init(rpc_session_t *ses, const char *logname)
 void
 rpc_deinit(rpc_session_t *ses)
 {
+  free(ses->rs_username);
+  free(ses->rs_password);
+
   free((void *)ses->rs_logname);
 }
diff --git a/rpc.h b/rpc.h
index e0fb3b2fa44d8458fa48c31a540a15db9cf79959..71e6fc72d3cf04c32757ffbcee14d6e5a41418e0 100644 (file)
--- a/rpc.h
+++ b/rpc.h
@@ -27,19 +27,21 @@ typedef struct rpc_session {
 
   uint32_t rs_seq;
 
-  unsigned int rs_authlevel;
   unsigned int rs_maxweight;
   unsigned int rs_is_async;
 
   struct th_subscription_list rs_subscriptions;
 
+  char *rs_username;
+  char *rs_password;
+
 } rpc_session_t;
 
 
 typedef struct rpc_cmd {
   const char *rc_name;
   htsmsg_t *(*rc_func)(rpc_session_t *ses, htsmsg_t *in, void *opaque);
-  int rc_authlevel;
+  int rc_privmask;
 } rpc_cmd_t;
 
 
@@ -49,10 +51,11 @@ void rpc_init(rpc_session_t *ses, const char *logname);
 void rpc_deinit(rpc_session_t *ses);
 
 htsmsg_t *rpc_dispatch(rpc_session_t *ses, htsmsg_t *in, rpc_cmd_t *cmds,
-                      void *opaque);
+                      void *opaque, struct sockaddr *peer);
 
 htsmsg_t *rpc_ok(rpc_session_t *ses);
 htsmsg_t *rpc_error(rpc_session_t *ses, const char *err);
+htsmsg_t *rpc_unauthorized(rpc_session_t *ses);
 
 
 #endif /* RPC_H_ */