Merge lp:~mardy/signon-apparmor-extension/new-signond into lp:signon-apparmor-extension

Proposed by Alberto Mardegan
Status: Merged
Approved by: Ken VanDine
Approved revision: 8
Merged at revision: 6
Proposed branch: lp:~mardy/signon-apparmor-extension/new-signond
Merge into: lp:signon-apparmor-extension
Diff against target: 449 lines (+216/-53)
11 files modified
.bzrignore (+2/-1)
debian/changelog (+3/-2)
debian/control (+4/-1)
src/access-control-manager.cpp (+61/-19)
src/access-control-manager.h (+15/-19)
src/src.pro (+3/-1)
tests/mock/apparmor.cpp (+44/-0)
tests/mock/mock.pro (+22/-0)
tests/tests.pro (+5/-0)
tests/tst_extension.cpp (+56/-9)
tests/tst_extension.pro (+1/-1)
To merge this branch: bzr merge lp:~mardy/signon-apparmor-extension/new-signond
Reviewer Review Type Date Requested Status
Ken VanDine Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+182379@code.launchpad.net

Commit message

Update to new signon API, add support for p2p connections

Dependency changes: latest signond, added build deps on dbus-1 and apparmor.

Description of the change

Update to new signon API, add support for p2p connections

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
8. By Alberto Mardegan

Tests: mock libapparmor and QDBusConnection::call()

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 :

Approve

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2013-08-23 14:35:22 +0000
3+++ .bzrignore 2013-09-04 06:56:12 +0000
4@@ -4,6 +4,7 @@
5 *.substvars
6 /debian/files
7 /debian/signon-apparmor-extension/
8-Makefile
9+Makefile*
10 moc_*
11+/tests/mock/libapparmor.so*
12 /tests/tst_extension
13
14=== modified file 'debian/changelog'
15--- debian/changelog 2013-08-06 12:17:11 +0000
16+++ debian/changelog 2013-09-04 06:56:12 +0000
17@@ -1,5 +1,6 @@
18-signon-apparmor-extension (0.0-0ubuntu1) UNRELEASED; urgency=low
19+signon-apparmor-extension (0.1-0ubuntu0) UNRELEASED; urgency=low
20
21 * Initial implementation.
22+ * Support p2p connections.
23
24- -- Alberto Mardegan <alberto.mardegan@canonical.com> Tue, 06 Aug 2013 14:52:28 +0300
25+ -- Alberto Mardegan <alberto.mardegan@canonical.com> Tue, 27 Aug 2013 15:31:46 +0300
26
27=== modified file 'debian/control'
28--- debian/control 2013-08-13 14:39:53 +0000
29+++ debian/control 2013-09-04 06:56:12 +0000
30@@ -5,7 +5,10 @@
31 pkg-config,
32 qt5-default,
33 qt5-qmake,
34- signond-dev,
35+ libapparmor-dev,
36+ libdbus-1-dev,
37+ signond-dev (>= 8.53),
38+ dbus-test-runner,
39 Standards-Version: 3.9.4
40 Section: libs
41 Homepage: https://launchpad.net/signon-apparmor-extension
42
43=== modified file 'src/access-control-manager.cpp'
44--- src/access-control-manager.cpp 2013-08-07 11:41:08 +0000
45+++ src/access-control-manager.cpp 2013-09-04 06:56:12 +0000
46@@ -24,9 +24,19 @@
47 #include <QDBusConnection>
48 #include <QDBusMessage>
49 #include <QDebug>
50+#include <dbus/dbus.h>
51+#include <sys/apparmor.h>
52
53 static const char keychainAppId[] = "SignondKeychain";
54
55+AccessReply::AccessReply(const SignOn::AccessRequest &request,
56+ QObject *parent):
57+ SignOn::AccessReply(request, parent)
58+{
59+ /* Always decline */
60+ QMetaObject::invokeMethod(this, "decline", Qt::QueuedConnection);
61+}
62+
63 AccessControlManager::AccessControlManager(QObject *parent):
64 SignOn::AbstractAccessControlManager(parent)
65 {
66@@ -41,10 +51,12 @@
67 return QLatin1String(keychainAppId);
68 }
69
70-bool AccessControlManager::isPeerAllowedToAccess(const QDBusMessage &peerMessage,
71- const QString &securityContext)
72+bool AccessControlManager::isPeerAllowedToAccess(
73+ const QDBusConnection &peerConnection,
74+ const QDBusMessage &peerMessage,
75+ const QString &securityContext)
76 {
77- QString appId = appIdOfPeer(peerMessage);
78+ QString appId = appIdOfPeer(peerConnection, peerMessage);
79
80 bool allowed = (appId == securityContext ||
81 securityContext == QLatin1String("*"));
82@@ -53,27 +65,57 @@
83 return allowed;
84 }
85
86-QString AccessControlManager::appIdOfPeer(const QDBusMessage &peerMessage)
87+QString AccessControlManager::appIdOfPeer(const QDBusConnection &peerConnection,
88+ const QDBusMessage &peerMessage)
89 {
90 QString uniqueConnectionId = peerMessage.service();
91 QString appId;
92
93- QDBusMessage msg =
94- QDBusMessage::createMethodCall("org.freedesktop.DBus",
95- "/org/freedesktop/DBus",
96- "org.freedesktop.DBus",
97- "GetConnectionAppArmorSecurityContext");
98- QVariantList args;
99- args << uniqueConnectionId;
100- msg.setArguments(args);
101- QDBusMessage reply =
102- QDBusConnection::sessionBus().call(msg, QDBus::Block);
103- if (reply.type() == QDBusMessage::ReplyMessage) {
104- appId = reply.arguments().value(0, QString()).toString();
105- qDebug() << "App ID:" << appId;
106+ if (uniqueConnectionId.isEmpty()) {
107+ /* it's a p2p connection; get the fd of the socket, and ask apparmor to
108+ * identify the peer. */
109+ DBusConnection *connection =
110+ (DBusConnection *)peerConnection.internalPointer();
111+ int fd = 0;
112+ dbus_bool_t ok = dbus_connection_get_unix_fd(connection, &fd);
113+ if (Q_LIKELY(ok)) {
114+ char *con = NULL, *mode = NULL;
115+ int ret = aa_getpeercon(fd, &con, &mode);
116+ if (Q_LIKELY(ret >= 0)) {
117+ appId = QString::fromUtf8(con);
118+ qDebug() << "App ID:" << appId;
119+ free(con);
120+ if (mode) free(mode);
121+ } else {
122+ qWarning() << "Couldn't get apparmor profile of peer";
123+ }
124+ } else {
125+ qWarning() << "Couldn't get fd of caller!";
126+ }
127 } else {
128- qWarning() << "Error getting app ID:" << reply.errorName() <<
129- reply.errorMessage();
130+ QDBusMessage msg =
131+ QDBusMessage::createMethodCall("org.freedesktop.DBus",
132+ "/org/freedesktop/DBus",
133+ "org.freedesktop.DBus",
134+ "GetConnectionAppArmorSecurityContext");
135+ QVariantList args;
136+ args << uniqueConnectionId;
137+ msg.setArguments(args);
138+ QDBusMessage reply =
139+ QDBusConnection::sessionBus().call(msg, QDBus::Block);
140+ if (reply.type() == QDBusMessage::ReplyMessage) {
141+ appId = reply.arguments().value(0, QString()).toString();
142+ qDebug() << "App ID:" << appId;
143+ } else {
144+ qWarning() << "Error getting app ID:" << reply.errorName() <<
145+ reply.errorMessage();
146+ }
147 }
148 return appId;
149 }
150+
151+SignOn::AccessReply *
152+AccessControlManager::handleRequest(const SignOn::AccessRequest &request)
153+{
154+ return new AccessReply(request, this);
155+}
156
157=== modified file 'src/access-control-manager.h'
158--- src/access-control-manager.h 2013-08-06 11:24:08 +0000
159+++ src/access-control-manager.h 2013-09-04 06:56:12 +0000
160@@ -24,6 +24,14 @@
161
162 #include <SignOn/AbstractAccessControlManager>
163
164+class AccessReply: public SignOn::AccessReply
165+{
166+ Q_OBJECT
167+
168+public:
169+ AccessReply(const SignOn::AccessRequest &request, QObject *parent = 0);
170+};
171+
172 class AccessControlManager: public SignOn::AbstractAccessControlManager
173 {
174 Q_OBJECT
175@@ -32,29 +40,17 @@
176 AccessControlManager(QObject *parent = 0);
177 ~AccessControlManager();
178
179- /*!
180- * Checks if a client process is allowed to access objects with a certain
181- * security context.
182- * The access type to be checked is read or execute.
183- * @param peerMessage, the request message sent over DBUS by the process.
184- * @param securityContext, the securityContext to be checked against.
185- * @returns true, if the peer is allowed, false otherwise.
186- */
187- bool isPeerAllowedToAccess(const QDBusMessage &peerMessage,
188+ bool isPeerAllowedToAccess(const QDBusConnection &peerConnection,
189+ const QDBusMessage &peerMessage,
190 const QString &securityContext) Q_DECL_OVERRIDE;
191
192- /*!
193- * Looks up for the application identifier of a specific client process.
194- * @param peerMessage, the request message sent over DBUS by the process.
195- * @returns the application identifier of the process, or an empty string
196- * if none found.
197- */
198- QString appIdOfPeer(const QDBusMessage &peerMessage) Q_DECL_OVERRIDE;
199+ QString appIdOfPeer(const QDBusConnection &peerConnection,
200+ const QDBusMessage &peerMessage) Q_DECL_OVERRIDE;
201
202- /*!
203- * @returns the application identifier of the keychain widget
204- */
205 QString keychainWidgetAppId() Q_DECL_OVERRIDE;
206+
207+ SignOn::AccessReply *handleRequest(const SignOn::AccessRequest &request)
208+ Q_DECL_OVERRIDE;
209 };
210
211 #endif // SIGNON_APPARMOR_ACCESS_CONTROL_MANAGER_H
212
213=== modified file 'src/src.pro'
214--- src/src.pro 2013-08-06 12:17:11 +0000
215+++ src/src.pro 2013-09-04 06:56:12 +0000
216@@ -19,7 +19,9 @@
217 -fvisibility=hidden
218
219 PKGCONFIG += \
220- SignOnExtension
221+ SignOnExtension \
222+ dbus-1 \
223+ libapparmor
224
225 # The following use of pkg-config + sed is a hack to workaround a qmake
226 # limitation: the CFLAGS variable is not used with the moc compiler, so the
227
228=== added directory 'tests/mock'
229=== added file 'tests/mock/apparmor.cpp'
230--- tests/mock/apparmor.cpp 1970-01-01 00:00:00 +0000
231+++ tests/mock/apparmor.cpp 2013-09-04 06:56:12 +0000
232@@ -0,0 +1,44 @@
233+/*
234+ * Copyright (C) 2013 Canonical Ltd.
235+ *
236+ * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
237+ *
238+ * This file is part of the signon-apparmor-extension
239+ *
240+ * This library is free software: you can redistribute it and/or modify it
241+ * under the terms of the GNU Lesser General Public License as published by
242+ * the Free Software Foundation, either version 3 of the License, or (at
243+ * your option) any later version.
244+ *
245+ * This library is distributed in the hope that it will be useful,
246+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
247+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
248+ * GNU Lesser General Public License for more details.
249+ *
250+ * You should have received a copy of the GNU Lesser General Public License
251+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
252+ */
253+
254+#include <QDBusConnection>
255+#include <QDBusMessage>
256+#include <QDebug>
257+#include <sys/apparmor.h>
258+
259+#define UNCONFINED_PROFILE "unconfined"
260+
261+int aa_getpeercon(int fd, char **con, char **mode)
262+{
263+ Q_UNUSED(fd);
264+ Q_UNUSED(mode);
265+ *con = strdup(UNCONFINED_PROFILE);
266+ return 0;
267+}
268+
269+QDBusMessage QDBusConnection::call(const QDBusMessage &message,
270+ QDBus::CallMode mode,
271+ int timeout) const
272+{
273+ Q_UNUSED(mode);
274+ Q_UNUSED(timeout);
275+ return message.createReply(QVariantList() << QStringLiteral(UNCONFINED_PROFILE));
276+}
277
278=== added file 'tests/mock/mock.pro'
279--- tests/mock/mock.pro 1970-01-01 00:00:00 +0000
280+++ tests/mock/mock.pro 2013-09-04 06:56:12 +0000
281@@ -0,0 +1,22 @@
282+include(../../common-project-config.pri)
283+
284+TARGET = apparmor
285+TEMPLATE = lib
286+
287+CONFIG += \
288+ debug \
289+ link_pkgconfig \
290+ qt
291+
292+QT += \
293+ core \
294+ dbus
295+
296+PKGCONFIG += \
297+ libapparmor
298+
299+# Error on undefined symbols
300+QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
301+
302+SOURCES += \
303+ apparmor.cpp
304
305=== added file 'tests/tests.pro'
306--- tests/tests.pro 1970-01-01 00:00:00 +0000
307+++ tests/tests.pro 2013-09-04 06:56:12 +0000
308@@ -0,0 +1,5 @@
309+TEMPLATE = subdirs
310+CONFIG += ordered
311+SUBDIRS = \
312+ mock \
313+ tst_extension.pro
314
315=== modified file 'tests/tst_extension.cpp'
316--- tests/tst_extension.cpp 2013-08-07 11:41:08 +0000
317+++ tests/tst_extension.cpp 2013-09-04 06:56:12 +0000
318@@ -19,28 +19,44 @@
319 * along with this library. If not, see <http://www.gnu.org/licenses/>.
320 */
321
322+#include <QDBusConnection>
323 #include <QDBusMessage>
324+#include <QDBusServer>
325 #include <QDebug>
326 #include <QPluginLoader>
327 #include <QTest>
328
329 #include <SignOn/AbstractAccessControlManager>
330
331+#define P2P_SOCKET "unix:path=/tmp/tst_extension_%1"
332+
333 class ExtensionTest: public QObject
334 {
335 Q_OBJECT
336
337+public:
338+ ExtensionTest();
339+
340 private Q_SLOTS:
341 void initTestCase();
342 void test_appId();
343+ void test_appId_p2p();
344 void test_access();
345 void test_accessWildcard();
346 void cleanupTestCase();
347
348 private:
349 SignOn::AbstractAccessControlManager *m_acm;
350+ QDBusConnection m_busConnection;
351+ QDBusConnection m_p2pConnection;
352 };
353
354+ExtensionTest::ExtensionTest():
355+ m_busConnection(QDBusConnection::sessionBus()),
356+ m_p2pConnection(QStringLiteral("uninitialized"))
357+{
358+}
359+
360 void ExtensionTest::initTestCase()
361 {
362 QPluginLoader pluginLoader(PLUGIN_PATH);
363@@ -53,25 +69,55 @@
364
365 m_acm = interface->accessControlManager(this);
366 QVERIFY(m_acm != 0);
367+
368+ QDBusServer *server;
369+ for (int i = 0; i < 10; i++) {
370+ server = new QDBusServer(QString::fromLatin1(P2P_SOCKET).arg(i), this);
371+ if (!server->isConnected()) {
372+ delete server;
373+ } else {
374+ break;
375+ }
376+ }
377+
378+ QVERIFY(server->isConnected());
379+
380+ m_p2pConnection = QDBusConnection::connectToPeer(server->address(),
381+ QStringLiteral("tst"));
382+ QVERIFY(m_p2pConnection.isConnected());
383 }
384
385 void ExtensionTest::test_appId()
386 {
387 /* forge a QDBusMessage */
388 QDBusMessage msg =
389- QDBusMessage::createMethodCall(":0.3", "/", "my.interface", "hi");
390- QString appId = m_acm->appIdOfPeer(msg);
391- /* At the moment, AppArmor doesn't implement the
392- * GetConnectionAppArmorSecurityContext method, so expect an error. */
393- QCOMPARE(appId, QString());
394+ QDBusMessage::createMethodCall(m_busConnection.baseService(),
395+ "/", "my.interface", "hi");
396+ QString appId = m_acm->appIdOfPeer(m_busConnection, msg);
397+ /* At the moment, AppArmor doesn't implement the
398+ * GetConnectionAppArmorSecurityContext method, so expect an error. */
399+ QCOMPARE(appId, QStringLiteral("unconfined"));
400+}
401+
402+void ExtensionTest::test_appId_p2p()
403+{
404+ /* forge a QDBusMessage */
405+ QDBusMessage msg =
406+ QDBusMessage::createMethodCall("", "/", "my.interface", "hi");
407+ QString appId = m_acm->appIdOfPeer(m_p2pConnection, msg);
408+ /* At the moment, AppArmor doesn't implement the
409+ * GetConnectionAppArmorSecurityContext method, so expect an error. */
410+ QCOMPARE(appId, QStringLiteral("unconfined"));
411 }
412
413 void ExtensionTest::test_access()
414 {
415 /* forge a QDBusMessage */
416 QDBusMessage msg =
417- QDBusMessage::createMethodCall(":0.3", "/", "my.interface", "hi");
418- bool allowed = m_acm->isPeerAllowedToAccess(msg, "anyContext");
419+ QDBusMessage::createMethodCall(m_busConnection.baseService(),
420+ "/", "my.interface", "hi");
421+ bool allowed = m_acm->isPeerAllowedToAccess(m_busConnection, msg,
422+ "anyContext");
423 /* At the moment, AppArmor doesn't implement the
424 * GetConnectionAppArmorSecurityContext method, so expect an error. */
425 QVERIFY(!allowed);
426@@ -81,8 +127,9 @@
427 {
428 /* forge a QDBusMessage */
429 QDBusMessage msg =
430- QDBusMessage::createMethodCall(":0.3", "/", "my.interface", "hi");
431- bool allowed = m_acm->isPeerAllowedToAccess(msg, "*");
432+ QDBusMessage::createMethodCall(m_busConnection.baseService(),
433+ "/", "my.interface", "hi");
434+ bool allowed = m_acm->isPeerAllowedToAccess(m_busConnection, msg, "*");
435 /* Everything is allowed to access "*" */
436 QVERIFY(allowed);
437 }
438
439=== renamed file 'tests/tests.pro' => 'tests/tst_extension.pro'
440--- tests/tests.pro 2013-08-07 11:41:08 +0000
441+++ tests/tst_extension.pro 2013-09-04 06:56:12 +0000
442@@ -22,7 +22,7 @@
443 SOURCES = \
444 tst_extension.cpp
445
446-check.commands = "./$${TARGET}"
447+check.commands = "LD_PRELOAD=mock/libapparmor.so dbus-test-runner -t ./$${TARGET}"
448 check.depends = $${TARGET}
449 QMAKE_EXTRA_TARGETS += check
450

Subscribers

People subscribed via source and target branches