You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by za...@apache.org on 2014/12/15 14:32:57 UTC

[08/37] cordova-ubuntu git commit: implement uri whitelist

implement uri whitelist


Project: http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/commit/9669f2ca
Tree: http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/tree/9669f2ca
Diff: http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/diff/9669f2ca

Branch: refs/heads/master
Commit: 9669f2caffc8368590e98262be508645d82d5107
Parents: 9b0b979
Author: Maxim Ermilov <ma...@canonical.com>
Authored: Wed Oct 1 22:24:01 2014 +0400
Committer: Maxim Ermilov <ma...@canonical.com>
Committed: Wed Oct 1 22:24:01 2014 +0400

----------------------------------------------------------------------
 CMakeLists.txt                    |   6 +-
 Cordovaqt/CordovaViewInternal.qml |   7 ++
 src/cordova.cpp                   |   8 ++-
 src/cordova.h                     |   5 ++
 src/cordova_config.cpp            |  44 +++++++++++++
 src/cordova_config.hpp            |  35 ++++++++++
 src/cordova_whitelist.cpp         | 116 +++++++++++++++++++++++++++++++++
 src/cordova_whitelist.hpp         |  49 ++++++++++++++
 src/qmlplugin.h                   |   7 ++
 9 files changed, 275 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/9669f2ca/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d4c978b..22ba714 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -90,12 +90,16 @@ ADD_LIBRARY(cordovaubuntuplugin SHARED
   src/cplugin.cpp
   src/cordova.cpp
   src/qmlplugin.cpp
+  src/cordova_whitelist.cpp
+  src/cordova_config.cpp
 
   src/cordova.h
   src/cplugin.h
   src/qmlplugin.h
+  src/cordova_whitelist.hpp
+  src/cordova_config.hpp
 )
-qt5_use_modules(cordovaubuntuplugin Widgets Quick)
+qt5_use_modules(cordovaubuntuplugin Widgets Quick Xml)
 
 #TODO use subprojects
 file(GLOB_RECURSE PLUGIN_SOURCES src/plugins/*.cpp)

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/9669f2ca/Cordovaqt/CordovaViewInternal.qml
----------------------------------------------------------------------
diff --git a/Cordovaqt/CordovaViewInternal.qml b/Cordovaqt/CordovaViewInternal.qml
index f662cc8..b0b986d 100644
--- a/Cordovaqt/CordovaViewInternal.qml
+++ b/Cordovaqt/CordovaViewInternal.qml
@@ -64,6 +64,13 @@ Item {
             anchors.fill: parent
             objectName: "webView"
 
+            onNavigationRequested: {
+                if (cordova.isUrlWhiteListed(request.url))
+                    request.action = WebView.AcceptRequest;
+                else
+                    request.action = WebView.IgnoreRequest;
+            }
+
             boundsBehavior: disallowOverscroll ? Flickable.StopAtBounds : Flickable.DragAndOvershootBounds
             property string scheme: "file"
             experimental.preferences.navigatorQtObjectEnabled: true

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/9669f2ca/src/cordova.cpp
----------------------------------------------------------------------
diff --git a/src/cordova.cpp b/src/cordova.cpp
index bff0574..1ca8e23 100644
--- a/src/cordova.cpp
+++ b/src/cordova.cpp
@@ -24,7 +24,9 @@
 #include <QQuickItem>
 #include <QQmlContext>
 
-Cordova::Cordova(QDir wwwDir, QString contentFile, QQuickItem *item, QObject *parent): QObject(parent), _item(item), _www(wwwDir) {
+Cordova::Cordova(QDir wwwDir, QString contentFile, QQuickItem *item, QObject *parent)
+    : QObject(parent), _item(item), _www(wwwDir), _config(_www.absoluteFilePath("../config.xml")) {
+
     qDebug() << "Using" << _www.absolutePath() << "as working dir";
 
     if (!_www.exists(contentFile))
@@ -76,6 +78,10 @@ QString Cordova::getSplashscreenPath() {
     return "";
 }
 
+const CordovaInternal::Config& Cordova::config() const {
+    return _config;
+}
+
 void Cordova::initPlugins() {
     QList<QDir> searchPath = {get_app_dir()};
 

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/9669f2ca/src/cordova.h
----------------------------------------------------------------------
diff --git a/src/cordova.h b/src/cordova.h
index c85de58..401a28d 100644
--- a/src/cordova.h
+++ b/src/cordova.h
@@ -22,6 +22,7 @@
 #include <cassert>
 
 #include "cplugin.h"
+#include "cordova_config.hpp"
 
 class QQuickView;
 class QQuickItem;
@@ -42,6 +43,8 @@ public:
     void popViewState(const QString &state);
     QString getSplashscreenPath();
 
+    const CordovaInternal::Config& config() const;
+
     template<typename A>
     QSharedPointer<CPlugin> getPlugin() {
         for (QSharedPointer<CPlugin> &plugin: _plugins) {
@@ -73,6 +76,8 @@ private:
     QDir _www;
     QString _mainUrl;
     QList<QString> _states;
+    CordovaInternal::Config _config;
+
     Q_DISABLE_COPY(Cordova)
 };
 

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/9669f2ca/src/cordova_config.cpp
----------------------------------------------------------------------
diff --git a/src/cordova_config.cpp b/src/cordova_config.cpp
new file mode 100644
index 0000000..b87bb9e
--- /dev/null
+++ b/src/cordova_config.cpp
@@ -0,0 +1,44 @@
+/*
+ *  Copyright 2014 Canonical Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include "cordova_config.hpp"
+#include <QtXml>
+
+using namespace CordovaInternal;
+
+Config::Config(const QString &xmlConfig) {
+    QDomDocument config;
+
+    QFile f1(xmlConfig);
+    f1.open(QIODevice::ReadOnly);
+
+    config.setContent(f1.readAll(), false);
+
+    QDomNodeList access = config.documentElement().elementsByTagName("access");
+    for (int i = 0; i < access.size(); ++i) {
+        QDomNode node = access.at(i);
+        QDomElement* element = static_cast<QDomElement*>(&node);
+
+        QString origin = element->attribute("origin");
+
+        _whitelist.addWhiteListEntry(origin, false);
+    }
+
+}
+
+const WhiteList& Config::whitelist() const {
+    return _whitelist;
+}

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/9669f2ca/src/cordova_config.hpp
----------------------------------------------------------------------
diff --git a/src/cordova_config.hpp b/src/cordova_config.hpp
new file mode 100644
index 0000000..71da1b5
--- /dev/null
+++ b/src/cordova_config.hpp
@@ -0,0 +1,35 @@
+/*
+ *  Copyright 2014 Canonical Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef CORDOVA_CONFIG_NMNMREQW525252
+#define CORDOVA_CONFIG_NMNMREQW525252
+
+#include <QtCore>
+#include "cordova_whitelist.hpp"
+
+namespace CordovaInternal {
+    class Config {
+    public:
+        explicit Config(const QString &xmlConfig);
+
+        const WhiteList& whitelist() const;
+    private:
+        WhiteList _whitelist;
+        Q_DISABLE_COPY(Config);
+    };
+}
+
+#endif

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/9669f2ca/src/cordova_whitelist.cpp
----------------------------------------------------------------------
diff --git a/src/cordova_whitelist.cpp b/src/cordova_whitelist.cpp
new file mode 100644
index 0000000..b4f2c9d
--- /dev/null
+++ b/src/cordova_whitelist.cpp
@@ -0,0 +1,116 @@
+/*
+ *  Copyright 2014 Canonical Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+#include "cordova_whitelist.hpp"
+
+using namespace CordovaInternal;
+
+WhiteList::WhiteList(): _unlimited(false), _empty(true) {
+}
+
+bool WhiteList::isUrlWhiteListed(const QString &uri) const {
+    // allow everything by default
+    if (_empty)
+        return true;
+
+    if (_unlimited)
+        return true;
+
+    QUrl parsedUri(uri);
+
+    for (const URLPattern &p: _whiteList) {
+        if (p.matches(parsedUri))
+            return true;
+    }
+    return false;
+}
+
+void WhiteList::addWhiteListEntry(const QString &origin, bool) {
+    _empty = false;
+
+    if (_unlimited)
+        return;
+    if (origin == "*") {
+        _unlimited = true;
+        return;
+    }
+
+    QRegExp parts("^((\\*|[A-Za-z-]+):(//)?)?(\\*|((\\*\\.)?[^*/:]+))?(:(\\d+))?(/.*)?");
+    if (parts.indexIn(origin) == -1)
+        return;
+
+    QString scheme = parts.cap(2);
+    QString host = parts.cap(4);
+
+    // Special case for two urls which are allowed to have empty hosts
+    if (("file" == scheme || "content" == scheme) && !host.size()) host = "*";
+    QString port = parts.cap(8);
+    QString path = parts.cap(9);
+
+    if (!scheme.size()) {
+        _whiteList.append(URLPattern("http", host, port, path));
+        _whiteList.append(URLPattern("https", host, port, path));
+    } else {
+        _whiteList.append(URLPattern(scheme, host, port, path));
+    }
+}
+
+WhiteList::URLPattern::URLPattern(const QString &scheme, const QString &host,
+                                  const QString &port, const QString &path) {
+
+    if (scheme.size() && "*" != scheme)
+        _scheme = QRegExp(regexFromPattern(scheme, false), Qt::CaseInsensitive);
+
+    if ("*" != host) {
+        if (host.startsWith("*.")) {
+            _host = QRegExp("([a-z0-9.-]*\\.)?" + regexFromPattern(host.mid(2), false), Qt::CaseInsensitive);
+        } else {
+            _host = QRegExp(regexFromPattern(host, false), Qt::CaseInsensitive);
+        }
+    }
+
+    if (!port.size() || "*" == port) {
+        _port = 0;
+    } else {
+        _port = port.toInt(nullptr, 10);
+    }
+
+    if (path.size() && "/*" != path) {
+        _path = QRegExp(regexFromPattern(path, true));
+    }
+}
+
+bool WhiteList::URLPattern::matches(QUrl uri) const {
+    return ((_scheme.isEmpty() || _scheme.exactMatch(uri.scheme())) &&
+            (_host.isEmpty() || _host.exactMatch(uri.host())) &&
+            (_port == 0 || _port == uri.port()) &&
+            (_path.isEmpty() || _path.exactMatch(uri.path())));
+}
+
+QString WhiteList::URLPattern::regexFromPattern(const QString &pattern, bool allowWildcards) const {
+    QString toReplace("\\.[]{}()^$?+|");
+
+    QString regex;
+    for (int i=0; i < pattern.size(); i++) {
+        QChar c = pattern[i];
+        if (c == '*' && allowWildcards) {
+            regex.append(".");
+        } else if (toReplace.indexOf(c) > -1) {
+            regex.append('\\');
+        }
+        regex.append(c);
+    }
+    return regex;
+}

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/9669f2ca/src/cordova_whitelist.hpp
----------------------------------------------------------------------
diff --git a/src/cordova_whitelist.hpp b/src/cordova_whitelist.hpp
new file mode 100644
index 0000000..66e949c
--- /dev/null
+++ b/src/cordova_whitelist.hpp
@@ -0,0 +1,49 @@
+/*
+ *  Copyright 2014 Canonical Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef CORDOVA_WHITELIST_HKJBNNBNM53452
+#define CORDOVA_WHITELIST_HKJBNNBNM53452
+
+#include <QtCore>
+
+// ported from https://github.com/apache/cordova-android/blob/master/framework/src/org/apache/cordova/Whitelist.java
+namespace CordovaInternal {
+    class WhiteList {
+    public:
+        WhiteList();
+
+        bool isUrlWhiteListed(const QString &uri) const;
+        void addWhiteListEntry(const QString &origin, bool subdomains);
+    private:
+        class URLPattern {
+        public:
+            URLPattern(const QString &scheme, const QString &host,
+                       const QString &port, const QString &path);
+            bool matches(QUrl uri) const;
+
+        private:
+            QString regexFromPattern(const QString &pattern, bool allowWildcards) const;
+            QRegExp _scheme, _host, _path;
+            int _port;
+        };
+
+        QList<URLPattern> _whiteList;
+        bool _unlimited, _empty;
+        Q_DISABLE_COPY(WhiteList);
+    };
+}
+
+#endif

http://git-wip-us.apache.org/repos/asf/cordova-ubuntu/blob/9669f2ca/src/qmlplugin.h
----------------------------------------------------------------------
diff --git a/src/qmlplugin.h b/src/qmlplugin.h
index f2a8965..ebe9adc 100644
--- a/src/qmlplugin.h
+++ b/src/qmlplugin.h
@@ -70,6 +70,13 @@ public:
         return _cordova->mainUrl();
     }
 
+    Q_INVOKABLE bool isUrlWhiteListed(const QString &uri) {
+        if (!_cordova.data()) {
+            return true;
+        }
+        return _cordova->config().whitelist().isUrlWhiteListed(uri);
+    }
+
 signals:
     void javaScriptExecNeeded(const QString &js);
     void pluginWantsToBeAdded(const QString &pluginName, QObject *pluginObject, const QString &pluginShortName);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org