Merge lp:~ken-vandine/content-hub/url-dispatcher into lp:content-hub

Proposed by Ken VanDine
Status: Merged
Approved by: Michael Sheldon
Approved revision: 209
Merged at revision: 209
Proposed branch: lp:~ken-vandine/content-hub/url-dispatcher
Merge into: lp:content-hub
Diff against target: 401 lines (+343/-0)
9 files modified
CMakeLists.txt (+1/-0)
debian/content-hub.install (+3/-0)
tools/CMakeLists.txt (+17/-0)
tools/send/CMakeLists.txt (+59/-0)
tools/send/autoexporter.cpp (+79/-0)
tools/send/autoexporter.h (+50/-0)
tools/send/content-hub-send.desktop (+9/-0)
tools/send/content-hub-send.url-dispatcher (+5/-0)
tools/send/exporter.cpp (+120/-0)
To merge this branch: bzr merge lp:~ken-vandine/content-hub/url-dispatcher
Reviewer Review Type Date Requested Status
Michael Sheldon (community) Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+259039@code.launchpad.net

Commit message

Added url-dispatcher integration. This allows export and share requests to be initiated by opening a url.

Description of the change

Added url-dispatcher integration. This allows export and share requests to be initiated by opening a url. For example, to create a share request to facebook you could open a url like:

"content:?pkg=com.ubuntu.developer.webapps.webapp-facebook&app=webapp-facebook&handler=share&url=http://www.ubuntu.com"

Parameters:
 * pkg - click package name (required)
 * app - click app name, ubuntu-app-launch will attempt to guess if not provided
 * ver - version of the click package, defaults to "current-user-version"
 * handler - export or share, defaults to defaults to "export"

A simple way to test this would be to run this from a shell:

url-dispatcher "content:?pkg=messaging-app&handler=share&url=http://www.ubuntu.com"

This will open the messaging-app and insert the link

File transfers are prohibited, for security reasons. So this only works for remote links and text shares.

To post a comment you must log in.
205. By Ken VanDine

tidy up a bit

206. By Ken VanDine

merged trunk

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
207. By Ken VanDine

Cleaned up appId creation and all text to be set

208. By Ken VanDine

white space cleanup

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ken VanDine (ken-vandine) wrote :

Are there any related MPs required for this MP to build/function as expected? Please list.

 * No

Is your branch in sync with latest trunk (e.g. bzr pull lp:trunk -> no changes)

 * Yes

Did you perform an exploratory manual test run of your code change and any related functionality on device or emulator?

 * Yes

Did you successfully run all tests found in your component's Test Plan (https://wiki.ubuntu.com/Process/Merges/TestPlan/content-hub) on device or emulator?

 * Yes, plus I ran the url-dispatcher test in the description. I'll add that to the test plan after this lands

If you changed the UI, was the change specified/approved by design?

 * No change

If you changed UI labels, did you update the pot file?

 * No change

If you changed the packaging (debian), did you add a core-dev as a reviewer to this MP?

 * There are packaging changes, I'm a core-dev

Revision history for this message
Michael Sheldon (michael-sheldon) wrote :

This doesn't appear to obey apparmor profiles, so as it stands this could potentially give unrestricted access to all files owned by the phablet user.

For example, creating a simple QML app that calls:

Qt.openUrlExternally("content:?pkg=com.ubuntu.developer.ken-vandine.hub-importer&url=file:///home/phablet/.ssh/known_hosts");

Will result in a user's SSH known_hosts file being sent to the hub-importer app (but potentially an app could be using this to send files directly back to itself and it could be grabbing much more important files if they exist, like ~/.ssh/id_rsa).

Unfortunately I don't think applying the apparmor profile of the app which called url-dispatcher will be enough either, as a malicious developer could create a website like http://mikeasoft.com/~mike/urlhack.php which does a header redirect to "content:?pkg=com.ubuntu.developer.ken-vandine.hub-importer&url=file:///home/phablet/.ssh/known_hosts". They would then call Qt.openUrlExternally("http://mikeasoft.com/~mike/urlhack.php") in their app, which would launch the webbrowser. The urlhack page would then cause the webbrowser to issue the request to the url-dispatcher instead of the originating app, and since the webbrowser is unconfined this would again provide a mechanism for accessing all of a user's files from a confined app.

review: Needs Fixing
209. By Ken VanDine

Don't support file transfers via url-dispatcher

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michael Sheldon (michael-sheldon) wrote :

Did you perform an exploratory manual test run of the code change and any related functionality on device or emulator?

 * Yes

Did CI run pass? If not, please explain why.

 * Yes

Have you checked that submitter has accurately filled out the submitter checklist and has taken no shortcut?

 * Yes

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2014-08-14 11:49:28 +0000
3+++ CMakeLists.txt 2015-05-15 14:21:06 +0000
4@@ -103,6 +103,7 @@
5 add_subdirectory(import)
6 add_subdirectory(examples)
7 add_subdirectory(tests)
8+add_subdirectory(tools)
9
10 install(DIRECTORY include DESTINATION ${CMAKE_INSTALL_PREFIX})
11
12
13=== modified file 'debian/content-hub.install'
14--- debian/content-hub.install 2014-11-18 14:59:03 +0000
15+++ debian/content-hub.install 2015-05-15 14:21:06 +0000
16@@ -1,6 +1,9 @@
17+usr/bin/content-hub-send
18 usr/bin/content-hub-service
19 usr/lib/*/content-hub
20 usr/share/click/hooks
21 usr/share/dbus-1
22 usr/share/glib-2.0/schemas
23 usr/share/locale/*/LC_MESSAGES/content-hub.mo
24+usr/share/applications/content-hub-send.desktop
25+usr/share/url-dispatcher/urls/content-hub-send.url-dispatcher
26
27=== added directory 'tools'
28=== added file 'tools/CMakeLists.txt'
29--- tools/CMakeLists.txt 1970-01-01 00:00:00 +0000
30+++ tools/CMakeLists.txt 2015-05-15 14:21:06 +0000
31@@ -0,0 +1,17 @@
32+# Copyright © 2015 Canonical Ltd.
33+#
34+# This program is free software: you can redistribute it and/or modify
35+# it under the terms of the GNU General Public License version 3 as
36+# published by the Free Software Foundation.
37+#
38+# This program is distributed in the hope that it will be useful,
39+# but WITHOUT ANY WARRANTY; without even the implied warranty of
40+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41+# GNU General Public License for more details.
42+#
43+# You should have received a copy of the GNU General Public License
44+# along with this program. If not, see <http://www.gnu.org/licenses/>.
45+#
46+# Authored by: Ken VanDine <ken.vandine@canonical.com>
47+
48+add_subdirectory(send)
49
50=== added directory 'tools/send'
51=== added file 'tools/send/CMakeLists.txt'
52--- tools/send/CMakeLists.txt 1970-01-01 00:00:00 +0000
53+++ tools/send/CMakeLists.txt 2015-05-15 14:21:06 +0000
54@@ -0,0 +1,59 @@
55+# Copyright © 2015 Canonical Ltd.
56+#
57+# This program is free software: you can redistribute it and/or modify
58+# it under the terms of the GNU General Public License version 3 as
59+# published by the Free Software Foundation.
60+#
61+# This program is distributed in the hope that it will be useful,
62+# but WITHOUT ANY WARRANTY; without even the implied warranty of
63+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
64+# GNU General Public License for more details.
65+#
66+# You should have received a copy of the GNU General Public License
67+# along with this program. If not, see <http://www.gnu.org/licenses/>.
68+#
69+# Authored by: Ken VanDine <ken.vandine@canonical.com>
70+
71+include_directories(
72+ ${CMAKE_CURRENT_BINARY_DIR}
73+ ${CMAKE_SOURCE_DIR}/src/com/ubuntu/content
74+ ${UBUNTU_LAUNCH_INCLUDE_DIRS}
75+)
76+
77+add_executable(
78+ content-hub-send
79+
80+ exporter.cpp
81+ autoexporter.cpp
82+ ${CMAKE_SOURCE_DIR}/src/com/ubuntu/content/debug.cpp
83+)
84+
85+qt5_use_modules(content-hub-send Core Gui DBus)
86+
87+set_target_properties(
88+ content-hub-send
89+ PROPERTIES
90+ AUTOMOC TRUE
91+)
92+
93+target_link_libraries(
94+ content-hub-send
95+
96+ content-hub
97+ ${UBUNTU_LAUNCH_LDFLAGS}
98+)
99+
100+install(
101+ TARGETS content-hub-send
102+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
103+)
104+
105+install(
106+ FILES content-hub-send.desktop
107+ DESTINATION ${CMAKE_INSTALL_DATADIR}/applications
108+)
109+
110+install(
111+ FILES content-hub-send.url-dispatcher
112+ DESTINATION share/url-dispatcher/urls
113+)
114
115=== added file 'tools/send/autoexporter.cpp'
116--- tools/send/autoexporter.cpp 1970-01-01 00:00:00 +0000
117+++ tools/send/autoexporter.cpp 2015-05-15 14:21:06 +0000
118@@ -0,0 +1,79 @@
119+/*
120+ * Copyright (C) 2015 Canonical, Ltd.
121+ *
122+ * This program is free software; you can redistribute it and/or modify
123+ * it under the terms of the GNU General Public License as published by
124+ * the Free Software Foundation; version 3.
125+ *
126+ * This program is distributed in the hope that it will be useful,
127+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
128+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
129+ * GNU General Public License for more details.
130+ *
131+ * You should have received a copy of the GNU General Public License
132+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
133+ *
134+ * Authored by: Ken VanDine <ken.vandine@canonical.com>
135+ */
136+
137+#include "autoexporter.h"
138+#include "debug.h"
139+
140+AutoExporter::AutoExporter()
141+{
142+ auto hub = cuc::Hub::Client::instance();
143+ hub->register_import_export_handler(this);
144+}
145+
146+void AutoExporter::setUrl(const QString& newUrl)
147+{
148+ url = newUrl;
149+}
150+
151+void AutoExporter::setText(const QString& newText)
152+{
153+ text = newText;
154+}
155+
156+void AutoExporter::handle_import(cuc::Transfer *transfer)
157+{
158+ TRACE() << Q_FUNC_INFO << "not implemented";
159+ Q_UNUSED(transfer);
160+}
161+
162+void AutoExporter::handle_export(cuc::Transfer *transfer)
163+{
164+ TRACE() << Q_FUNC_INFO;
165+ if (transfer == nullptr) {
166+ TRACE() << Q_FUNC_INFO << "Transfer null";
167+ return;
168+ }
169+
170+ cuc::Item item;
171+
172+ if (!url.isEmpty())
173+ item.setUrl(QUrl(url));
174+ if (!text.isEmpty())
175+ item.setText(text);
176+
177+ QVector<cuc::Item> items;
178+ items << item;
179+ transfer->charge(items);
180+ connect(transfer, SIGNAL(stateChanged()), this, SLOT(stateChanged()));
181+ TRACE() << Q_FUNC_INFO << "Items:" << items.count();
182+}
183+
184+void AutoExporter::handle_share(cuc::Transfer *transfer)
185+{
186+ TRACE() << Q_FUNC_INFO << "not implemented";
187+ Q_UNUSED(transfer);
188+}
189+
190+void AutoExporter::stateChanged()
191+{
192+ cuc::Transfer *transfer = static_cast<cuc::Transfer*>(sender());
193+ TRACE() << Q_FUNC_INFO << "STATE:" << transfer->state();
194+
195+ if (transfer->state() == cuc::Transfer::collected)
196+ QCoreApplication::instance()->quit();
197+}
198
199=== added file 'tools/send/autoexporter.h'
200--- tools/send/autoexporter.h 1970-01-01 00:00:00 +0000
201+++ tools/send/autoexporter.h 2015-05-15 14:21:06 +0000
202@@ -0,0 +1,50 @@
203+/*
204+ * Copyright (C) 2015 Canonical, Ltd.
205+ *
206+ * This program is free software; you can redistribute it and/or modify
207+ * it under the terms of the GNU General Public License as published by
208+ * the Free Software Foundation; version 3.
209+ *
210+ * This program is distributed in the hope that it will be useful,
211+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
212+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
213+ * GNU General Public License for more details.
214+ *
215+ * You should have received a copy of the GNU General Public License
216+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
217+ *
218+ * Authored by: Ken VanDine <ken.vandine@canonical.com>
219+ */
220+
221+#ifndef AUTOEXPORTER_H
222+#define AUTOEXPORTER_H
223+
224+#include <QObject>
225+#include <QString>
226+#include <com/ubuntu/content/hub.h>
227+#include <com/ubuntu/content/transfer.h>
228+#include <com/ubuntu/content/import_export_handler.h>
229+
230+namespace cuc = com::ubuntu::content;
231+
232+class AutoExporter : public cuc::ImportExportHandler
233+{
234+ Q_OBJECT
235+
236+public:
237+ AutoExporter();
238+
239+public slots:
240+ Q_INVOKABLE void handle_import(cuc::Transfer*);
241+ Q_INVOKABLE void handle_export(cuc::Transfer*);
242+ Q_INVOKABLE void handle_share(cuc::Transfer*);
243+ Q_INVOKABLE void stateChanged();
244+ void setUrl(const QString&);
245+ void setText(const QString&);
246+
247+private:
248+ QString url;
249+ QString text;
250+};
251+
252+#endif // AUTOEXPORTER_H
253
254=== added file 'tools/send/content-hub-send.desktop'
255--- tools/send/content-hub-send.desktop 1970-01-01 00:00:00 +0000
256+++ tools/send/content-hub-send.desktop 2015-05-15 14:21:06 +0000
257@@ -0,0 +1,9 @@
258+[Desktop Entry]
259+Name=Content Hub Send
260+Comment=Content Hub Send
261+Exec=content-hub-send %U
262+Icon=
263+Terminal=false
264+Type=Application
265+OnlyShowIn=Old
266+X-Ubuntu-Touch=true
267
268=== added file 'tools/send/content-hub-send.url-dispatcher'
269--- tools/send/content-hub-send.url-dispatcher 1970-01-01 00:00:00 +0000
270+++ tools/send/content-hub-send.url-dispatcher 2015-05-15 14:21:06 +0000
271@@ -0,0 +1,5 @@
272+[
273+ {
274+ "protocol": "content"
275+ }
276+]
277
278=== added file 'tools/send/exporter.cpp'
279--- tools/send/exporter.cpp 1970-01-01 00:00:00 +0000
280+++ tools/send/exporter.cpp 2015-05-15 14:21:06 +0000
281@@ -0,0 +1,120 @@
282+/*
283+ * Copyright (C) 2015 Canonical, Ltd.
284+ *
285+ * This program is free software; you can redistribute it and/or modify
286+ * it under the terms of the GNU General Public License as published by
287+ * the Free Software Foundation; version 3.
288+ *
289+ * This program is distributed in the hope that it will be useful,
290+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
291+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
292+ * GNU General Public License for more details.
293+ *
294+ * You should have received a copy of the GNU General Public License
295+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
296+ *
297+ * Authored by: Ken VanDine <ken.vandine@canonical.com>
298+ */
299+
300+#include <QCoreApplication>
301+#include <QStringList>
302+#include <QUrlQuery>
303+#include <ubuntu-app-launch.h>
304+
305+#include "autoexporter.h"
306+#include "debug.h"
307+
308+namespace cuc = com::ubuntu::content;
309+
310+int main(int argc, char *argv[])
311+{
312+ QCoreApplication a(argc, argv);
313+ if (qgetenv("APP_ID").isEmpty()) {
314+ qputenv("APP_ID", "content-hub-send-file");
315+ }
316+
317+ /* read environment variables */
318+ QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
319+ if (environment.contains(QLatin1String("CONTENT_HUB_LOGGING_LEVEL"))) {
320+ bool isOk;
321+ int value = environment.value(
322+ QLatin1String("CONTENT_HUB_LOGGING_LEVEL")).toInt(&isOk);
323+ if (isOk)
324+ setLoggingLevel(value);
325+ }
326+
327+ std::string handler = "export";
328+ QString url, text, appId;
329+ gchar* pkg = NULL;
330+ gchar* app = NULL;
331+ gchar* ver = NULL;
332+
333+ /* URL handled looks like:
334+ * content:?pkg=foo&app=bar&ver=0.1&url=path&text=text
335+ * Only pkg is required.
336+ */
337+
338+ QUrlQuery* query = new QUrlQuery(a.arguments().at(1).split("?").at(1));
339+ TRACE() << "Handling URL:" << query->query();
340+
341+ if (query->hasQueryItem("pkg"))
342+ pkg = g_strdup(query->queryItemValue("pkg").toStdString().c_str());
343+ else {
344+ qWarning() << "PKG is required";
345+ return 1;
346+ }
347+ if (query->hasQueryItem("app"))
348+ app = g_strdup(query->queryItemValue("app").toStdString().c_str());
349+ if (query->hasQueryItem("ver"))
350+ ver = g_strdup(query->queryItemValue("ver").toStdString().c_str());
351+ if (query->hasQueryItem("handler"))
352+ handler = query->queryItemValue("handler").toStdString();
353+ url = query->queryItemValue("url");
354+
355+ /* Don't support file transfers via url-dispatcher
356+ * it would allow unconfined access to any file simply
357+ * by constructing an evil file url
358+ */
359+ if (url.startsWith("file")) {
360+ qWarning() << "File transfers are not supported";
361+ return 1;
362+ }
363+
364+ text = query->queryItemValue("text");
365+ TRACE() << "URL:" << url;
366+ TRACE() << "PKG:" << pkg;
367+ TRACE() << "APP:" << app;
368+ TRACE() << "VER:" << ver;
369+ TRACE() << "HANDLER:" << handler.c_str();
370+
371+ appId = QString::fromLocal8Bit(ubuntu_app_launch_triplet_to_app_id(pkg, app, ver));
372+ if (appId.isNull())
373+ appId = QString(pkg);
374+
375+ if (appId.isEmpty())
376+ {
377+ qWarning() << "Unable to determine peer";
378+ return 1;
379+ }
380+
381+ AutoExporter exporter;
382+ if (!url.isEmpty())
383+ exporter.setUrl(url);
384+
385+ if (!text.isEmpty())
386+ exporter.setText(text);
387+
388+ TRACE() << "APP_ID:" << appId;
389+
390+ auto hub = cuc::Hub::Client::instance();
391+ auto peer = cuc::Peer{appId};
392+ if (handler == "share") {
393+ auto transfer = hub->create_share_to_peer(peer);
394+ exporter.handle_export(transfer);
395+ } else {
396+ auto transfer = hub->create_export_to_peer(peer);
397+ exporter.handle_export(transfer);
398+ }
399+
400+ return a.exec();
401+}

Subscribers

People subscribed via source and target branches