extra whitelist of allowed paths

This commit is contained in:
Marco Martin 2013-12-27 14:59:37 +01:00
parent 10f412ca4a
commit 86369030de
4 changed files with 45 additions and 11 deletions

View File

@ -30,12 +30,30 @@ PackageUrlInterceptor::PackageUrlInterceptor(QQmlEngine *engine, const Plasma::P
m_package(p),
m_engine(engine)
{
foreach (const QString &import, m_engine->importPathList()) {
m_allowedPaths << import;
}
}
PackageUrlInterceptor::~PackageUrlInterceptor()
{
}
void PackageUrlInterceptor::addAllowedPath(const QString &path)
{
m_allowedPaths << path;
}
void PackageUrlInterceptor::removeAllowedPath(const QString &path)
{
m_allowedPaths.removeAll(path);
}
QStringList PackageUrlInterceptor::allowedPaths() const
{
return m_allowedPaths;
}
QUrl PackageUrlInterceptor::intercept(const QUrl &path, QQmlAbstractUrlInterceptor::DataType type)
{
//qDebug() << "Intercepted URL:" << path;
@ -86,18 +104,17 @@ QUrl PackageUrlInterceptor::intercept(const QUrl &path, QQmlAbstractUrlIntercept
//forbid to load random absolute paths
} else {
foreach (const QString &import, m_engine->importPathList()) {
//it's from an import, good
//TODO: implement imports whitelist?
if (path.path().startsWith(import)) {
//qDebug() << "Found import, access granted" << path;
foreach (const QString &allowed, m_allowedPaths) {
//it's from an allowed, good
if (path.path().startsWith(allowed)) {
//qDebug() << "Found allowed, access granted" << path;
//check if there is a platform specific file that overrides this import
//check if there is a platform specific file that overrides this allowed
foreach (const QString &platform, KDeclarative::runtimePlatform()) {
//qDebug() << "Trying" << platform;
//search for a platformqml/ path sibling of this import path
const QString &platformPath = import+QStringLiteral("/../platformqml/")+platform+path.path().mid(import.length());
//search for a platformqml/ path sibling of this allowed path
const QString &platformPath = allowed+QStringLiteral("/../platformqml/")+platform+path.path().mid(allowed.length());
const QFile f(platformPath);
//qDebug() << "Found a platform specific file:" << QUrl::fromLocalFile(platformPath)<<f.exists();
@ -108,11 +125,14 @@ QUrl PackageUrlInterceptor::intercept(const QUrl &path, QQmlAbstractUrlIntercept
return path;
}
}
qWarning() << "WARNING: Access denied for URL" << path << m_package.path();
}
//for now, just allow qmldirs
} else {
return path;
}
return path;
qWarning() << "WARNING: Access denied for URL" << path << m_package.path();
return QUrl();
}

View File

@ -35,6 +35,10 @@ public:
PackageUrlInterceptor(QQmlEngine *engine, const Plasma::Package &p);
virtual ~PackageUrlInterceptor();
void addAllowedPath(const QString &path);
void removeAllowedPath(const QString &path);
QStringList allowedPaths() const;
virtual QUrl intercept(const QUrl &path, QQmlAbstractUrlInterceptor::DataType type);
static inline QByteArray prefixForType(QQmlAbstractUrlInterceptor::DataType type, const QString &fileName)
@ -68,6 +72,7 @@ public:
private:
Plasma::Package m_package;
QStringList m_allowedPaths;
QQmlEngine *m_engine;
};

View File

@ -111,7 +111,9 @@ void AppletInterface::init()
//Hook generic url resolution to the applet package as well
//TODO: same thing will have to be done for every qqmlengine: PackageUrlInterceptor is material for plasmaquick?
engine->setUrlInterceptor(new PackageUrlInterceptor(engine, m_appletScriptEngine->package()));
PackageUrlInterceptor *interceptor = new PackageUrlInterceptor(engine, m_appletScriptEngine->package());
interceptor->addAllowedPath(applet()->containment()->corona()->package().path());
engine->setUrlInterceptor(interceptor);
m_qmlObject->setSource(QUrl::fromLocalFile(m_appletScriptEngine->mainScript()));

View File

@ -50,6 +50,7 @@
#include <kactivities/info.h>
#include "kdeclarative/configpropertymap.h"
#include <packageurlinterceptor.h>
ContainmentInterface::ContainmentInterface(DeclarativeAppletScript *parent)
: AppletInterface(parent),
@ -111,12 +112,18 @@ void ContainmentInterface::init()
}
Plasma::Package pkg = Plasma::PluginLoader::self()->loadPackage("Plasma/Generic");
if (defaults.isValid()) {
pkg.setPath(defaults.readEntry("ToolBox", "org.kde.desktoptoolbox"));
} else {
pkg.setPath("org.kde.desktoptoolbox");
}
PackageUrlInterceptor *interceptor = dynamic_cast<PackageUrlInterceptor *>(m_qmlObject->engine()->urlInterceptor());
if (interceptor) {
interceptor->addAllowedPath(pkg.path());
}
if (pkg.isValid()) {
QObject *toolBoxObject = m_qmlObject->createObjectFromSource(QUrl::fromLocalFile(pkg.filePath("mainscript")));