[UPNP/JSONRPC] Allow usage of path that are inside sources + add source
authorTolriq <Tolriq@gmail.com>
Sat, 18 May 2013 13:25:38 +0000 (15:25 +0200)
committerTolriq <Tolriq@gmail.com>
Mon, 3 Jun 2013 20:20:22 +0000 (22:20 +0200)
setting allowSharing

Continuation of 1220d8c4a9
Add a source flag allowsharing defaulting to true to allow or disallow
access to a source from UPNP/WebServer

The checks are now available as a function in FileUtils and common to UPNP and JSON
Also make the check correctly works in JSON as current implementation have flow allowing browsing any directory with Files.GetDirectory.

xbmc/MediaSource.cpp
xbmc/MediaSource.h
xbmc/interfaces/json-rpc/FileOperations.cpp
xbmc/network/httprequesthandler/HTTPVfsHandler.cpp
xbmc/network/upnp/UPnPServer.cpp
xbmc/settings/MediaSourceSettings.cpp
xbmc/utils/FileUtils.cpp
xbmc/utils/FileUtils.h

index 002028e..eb1b804 100644 (file)
@@ -54,6 +54,7 @@ void CMediaSource::FromNameAndPaths(const CStdString &category, const CStdString
   m_strLockCode = "0";
   m_iBadPwdCount = 0;
   m_iHasLock = 0;
+  m_allowSharing = true;
 
   if (URIUtils::IsMultiPath(strPath))
     m_iDriveType = SOURCE_TYPE_VPATH;
index cc8cf3b..941211f 100644 (file)
@@ -41,7 +41,7 @@ public:
     SOURCE_TYPE_VPATH        = 5,
     SOURCE_TYPE_REMOVABLE    = 6
   };
-  CMediaSource() { m_iDriveType=SOURCE_TYPE_UNKNOWN; m_iLockMode=LOCK_MODE_EVERYONE; m_iBadPwdCount=0; m_iHasLock=0; m_ignore=false; };
+  CMediaSource() { m_iDriveType=SOURCE_TYPE_UNKNOWN; m_iLockMode=LOCK_MODE_EVERYONE; m_iBadPwdCount=0; m_iHasLock=0; m_ignore=false; m_allowSharing=true; };
   virtual ~CMediaSource() {};
 
   bool operator==(const CMediaSource &right) const;
@@ -98,6 +98,7 @@ public:
 
   std::vector<CStdString> vecPaths;
   bool m_ignore; /// <Do not store in xml
+  bool m_allowSharing; /// <Allow browsing of source from UPnP / WebServer
 };
 
 /*!
index 9052494..87d6ad1 100644 (file)
 #include "Util.h"
 #include "URL.h"
 #include "utils/URIUtils.h"
+#include "utils/FileUtils.h"
 
 using namespace XFILE;
 using namespace JSONRPC;
 
-static const unsigned int SourcesSize = 5;
-static CStdString SourceNames[] = { "programs", "files", "video", "music", "pictures" };
-
 JSONRPC_STATUS CFileOperations::GetRootDirectory(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CStdString media = parameterObject["media"].asString();
@@ -82,15 +80,8 @@ JSONRPC_STATUS CFileOperations::GetDirectory(const CStdString &method, ITranspor
   CFileItemList items;
   CStdString strPath = parameterObject["directory"].asString();
 
-  // Check if this directory is part of a source and whether it's locked
-  bool isSource;
-  for (unsigned int index = 0; index < SourcesSize; index++)
-  {
-    VECSOURCES* sources = CMediaSourceSettings::Get().GetSources(SourceNames[index]);
-    int sourceIndex = CUtil::GetMatchingSource(strPath, *sources, isSource);
-    if (sourceIndex >= 0 && sourceIndex < (int)sources->size() && sources->at(sourceIndex).m_iHasLock == 2)
-      return InvalidParams;
-  }
+  if (!CFileUtils::RemoteAccessAllowed(strPath))
+    return InvalidParams;
 
   CStdStringArray regexps;
   CStdString extensions = "";
@@ -180,6 +171,9 @@ JSONRPC_STATUS CFileOperations::GetFileDetails(const CStdString &method, ITransp
   if (!CFile::Exists(file))
     return InvalidParams;
 
+  if (!CFileUtils::RemoteAccessAllowed(file))
+    return InvalidParams;
+
   CStdString path;
   URIUtils::GetDirectory(file, path);
 
index 522809d..a73f733 100644 (file)
@@ -64,8 +64,8 @@ int CHTTPVfsHandler::HandleHTTPRequest(const HTTPRequest &request)
 
           for (VECSOURCES::const_iterator source = sources->begin(); source != sources->end() && !accessible; source++)
           {
-            // don't allow access to locked sources
-            if (source->m_iHasLock == 2)
+            // don't allow access to locked / disabled sharing sources
+            if (source->m_iHasLock == 2 || !source->m_allowSharing)
               continue;
 
             for (vector<CStdString>::const_iterator path = source->vecPaths.begin(); path != source->vecPaths.end(); path++)
index 9bbd6d8..2549a70 100644 (file)
@@ -24,6 +24,7 @@
 #include "video/VideoDatabase.h"
 #include "guilib/GUIWindowManager.h"
 #include "xbmc/GUIUserMessages.h"
+#include "utils/FileUtils.h"
 
 using namespace std;
 using namespace ANNOUNCEMENT;
@@ -475,23 +476,7 @@ static NPT_String TranslateWMPObjectId(NPT_String id)
 NPT_Result
 ObjectIDValidate(const NPT_String& id)
 {
-    if(id.Find("..") != -1)
-        return NPT_ERROR_NO_SUCH_FILE;
-    if(id.StartsWith("virtualpath://upnproot/"))
-        return NPT_SUCCESS;
-    else if(id.StartsWith("musicdb://"))
-        return NPT_SUCCESS;
-    else if(id.StartsWith("videodb://"))
-        return NPT_SUCCESS;
-    else if(id.StartsWith("library://video"))
-        return NPT_SUCCESS;
-    else if(id.StartsWith("sources://video"))
-        return NPT_SUCCESS;
-    else if(id.StartsWith("special://musicplaylists"))
-        return NPT_SUCCESS;
-    else if(id.StartsWith("special://profile/playlists"))
-        return NPT_SUCCESS;
-    else if(id.StartsWith("special://videoplaylists"))
+    if (CFileUtils::RemoteAccessAllowed(id.GetChars()))
         return NPT_SUCCESS;
     return NPT_ERROR_NO_SUCH_FILE;
 }
index 531e586..0f06017 100644 (file)
@@ -416,6 +416,8 @@ bool CMediaSourceSettings::GetSource(const std::string &category, const TiXmlNod
   if (pThumbnailNode && pThumbnailNode->FirstChild())
     share.m_strThumbnailImage = pThumbnailNode->FirstChild()->Value();
 
+  XMLUtils::GetBoolean(source, "allowsharing", share.m_allowSharing);
+
   return true;
 }
 
@@ -485,9 +487,12 @@ bool CMediaSourceSettings::SetSources(TiXmlNode *root, const char *section, cons
       XMLUtils::SetString(&source, "lockcode", share.m_strLockCode);
       XMLUtils::SetInt(&source, "badpwdcount", share.m_iBadPwdCount);
     }
+
     if (!share.m_strThumbnailImage.empty())
       XMLUtils::SetPath(&source, "thumbnail", share.m_strThumbnailImage);
 
+    XMLUtils::SetBoolean(&source, "allowsharing", share.m_allowSharing);
+
     sectionNode->InsertEndChild(source);
   }
 
index e47a87d..1ad29c9 100644 (file)
@@ -9,6 +9,10 @@
 #include "URIUtils.h"
 #include "filesystem/MultiPathDirectory.h"
 #include <vector>
+#include "settings/MediaSourceSettings.h"
+#include "Util.h"
+#include "StringUtils.h"
+#include "URL.h"
 
 using namespace XFILE;
 using namespace std;
@@ -81,3 +85,42 @@ bool CFileUtils::RenameFile(const CStdString &strFile)
   }
   return false;
 }
+
+bool CFileUtils::RemoteAccessAllowed(const CStdString &strPath)
+{
+  const unsigned int SourcesSize = 5;
+  CStdString SourceNames[] = { "programs", "files", "video", "music", "pictures" };
+
+  string realPath = URIUtils::GetRealPath(strPath);
+  // for rar:// and zip:// paths we need to extract the path to the archive
+  // instead of using the VFS path
+  while (URIUtils::IsInArchive(realPath))
+    realPath = CURL(realPath).GetHostName();
+
+  if (StringUtils::StartsWith(realPath, "virtualpath://upnproot/"))
+    return true;
+  else if (StringUtils::StartsWith(realPath, "musicdb://"))
+    return true;
+  else if (StringUtils::StartsWith(realPath, "videodb://"))
+    return true;
+  else if (StringUtils::StartsWith(realPath, "library://video"))
+    return true;
+  else if (StringUtils::StartsWith(realPath, "sources://video"))
+    return true;
+  else if (StringUtils::StartsWith(realPath, "special://musicplaylists"))
+    return true;
+  else if (StringUtils::StartsWith(realPath, "special://profile/playlists"))
+    return true;
+  else if (StringUtils::StartsWith(realPath, "special://videoplaylists"))
+    return true;
+
+  bool isSource;
+  for (unsigned int index = 0; index < SourcesSize; index++)
+  {
+    VECSOURCES* sources = CMediaSourceSettings::Get().GetSources(SourceNames[index]);
+    int sourceIndex = CUtil::GetMatchingSource(realPath, *sources, isSource);
+    if (sourceIndex >= 0 && sourceIndex < (int)sources->size() && sources->at(sourceIndex).m_iHasLock != 2 && sources->at(sourceIndex).m_allowSharing)
+      return true;
+  }
+  return false;
+}
\ No newline at end of file
index 7d8fce4..20cac66 100644 (file)
@@ -7,4 +7,5 @@ public:
   static bool DeleteItem(const CFileItemPtr &item, bool force=false);
   static bool DeleteItem(const CStdString &strPath, bool force=false);
   static bool RenameFile(const CStdString &strFile);
+  static bool RemoteAccessAllowed(const CStdString &strPath);
 };