signon 8.54

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

signondaemonadaptor.cpp
Go to the documentation of this file.
1 /*
2 * This file is part of signon
3 *
4 * Copyright (C) 2009-2010 Nokia Corporation.
5 * Copyright (C) 2011 Intel Corporation.
6 * Copyright (C) 2013 Canonical Ltd.
7 *
8 * Contact: Aurel Popirtac <ext-aurel.popirtac@nokia.com>
9 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
10 * Contact: Jussi Laako <jussi.laako@linux.intel.com>
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * version 2.1 as published by the Free Software Foundation.
15 *
16 * This library is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27 #include "signondaemonadaptor.h"
28 #include "signondisposable.h"
29 #include "accesscontrolmanagerhelper.h"
30
31 namespace SignonDaemonNS {
32
33 SignonDaemonAdaptor::SignonDaemonAdaptor(SignonDaemon *parent):
34 QDBusAbstractAdaptor(parent),
35 m_parent(parent)
36 {
37 setAutoRelaySignals(false);
38 }
39
40 SignonDaemonAdaptor::~SignonDaemonAdaptor()
41 {
42 }
43
44 void SignonDaemonAdaptor::registerNewIdentity(QDBusObjectPath &objectPath)
45 {
46 QObject *identity = m_parent->registerNewIdentity();
47 objectPath = registerObject(parentDBusContext().connection(), identity);
48
49 SignonDisposable::destroyUnused();
50 }
51
52 void SignonDaemonAdaptor::securityErrorReply()
53 {
54 securityErrorReply(parentDBusContext().connection(),
55 parentDBusContext().message());
56 }
57
58 void SignonDaemonAdaptor::securityErrorReply(const QDBusConnection &conn,
59 const QDBusMessage &msg)
60 {
61 QString errMsg;
62 QTextStream(&errMsg) << SIGNOND_PERMISSION_DENIED_ERR_STR
63 << "Method:"
64 << msg.member();
65
66 msg.setDelayedReply(true);
67 QDBusMessage errReply =
68 msg.createErrorReply(SIGNOND_PERMISSION_DENIED_ERR_NAME,
69 errMsg);
70 conn.send(errReply);
71 TRACE() << "Method FAILED Access Control check:" << msg.member();
72 }
73
74 bool SignonDaemonAdaptor::handleLastError(const QDBusConnection &conn,
75 const QDBusMessage &msg)
76 {
77 if (!m_parent->lastErrorIsValid()) return false;
78
79 msg.setDelayedReply(true);
80 QDBusMessage errReply =
81 msg.createErrorReply(m_parent->lastErrorName(),
82 m_parent->lastErrorMessage());
83 conn.send(errReply);
84 return true;
85 }
86
87 QDBusObjectPath
88 SignonDaemonAdaptor::registerObject(const QDBusConnection &connection,
89 QObject *object)
90 {
91 QString path = object->objectName();
92
93 if (connection.objectRegisteredAt(path) != object) {
94 QDBusConnection conn(connection);
95 if (!conn.registerObject(path, object,
96 QDBusConnection::ExportAdaptors)) {
97 BLAME() << "Object registration failed:" << object <<
98 conn.lastError();
99 }
100 }
101 return QDBusObjectPath(path);
102 }
103
104 void SignonDaemonAdaptor::getIdentity(const quint32 id,
105 QDBusObjectPath &objectPath,
106 QVariantMap &identityData)
107 {
108 AccessControlManagerHelper *acm = AccessControlManagerHelper::instance();
109 QDBusMessage msg = parentDBusContext().message();
110 QDBusConnection conn = parentDBusContext().connection();
111 if (!acm->isPeerAllowedToUseIdentity(conn, msg, id)) {
112 SignOn::AccessReply *reply =
113 acm->requestAccessToIdentity(conn, msg, id);
114 QObject::connect(reply, SIGNAL(finished()),
115 this, SLOT(onIdentityAccessReplyFinished()));
116 msg.setDelayedReply(true);
117 return;
118 }
119
120 QObject *identity = m_parent->getIdentity(id, identityData);
121 if (handleLastError(conn, msg)) return;
122
123 objectPath = registerObject(conn, identity);
124
125 SignonDisposable::destroyUnused();
126 }
127
128 void SignonDaemonAdaptor::onIdentityAccessReplyFinished()
129 {
130 SignOn::AccessReply *reply = qobject_cast<SignOn::AccessReply*>(sender());
131 Q_ASSERT(reply != 0);
132
133 reply->deleteLater();
134 QDBusConnection connection = reply->request().peerConnection();
135 QDBusMessage message = reply->request().peerMessage();
136 quint32 id = reply->request().identity();
137 AccessControlManagerHelper *acm = AccessControlManagerHelper::instance();
138
139 if (!reply->isAccepted() ||
140 !acm->isPeerAllowedToUseIdentity(connection, message, id)) {
141 securityErrorReply(connection, message);
142 return;
143 }
144
145 QVariantMap identityData;
146 QObject *identity = m_parent->getIdentity(id, identityData);
147 if (handleLastError(connection, message)) return;
148
149 QDBusObjectPath objectPath = registerObject(connection, identity);
150
151 QVariantList args;
152 args << QVariant::fromValue(objectPath);
153 args << identityData;
154 connection.send(message.createReply(args));
155
156 SignonDisposable::destroyUnused();
157 }
158
159 QStringList SignonDaemonAdaptor::queryMethods()
160 {
161 return m_parent->queryMethods();
162 }
163
164 QString SignonDaemonAdaptor::getAuthSessionObjectPath(const quint32 id,
165 const QString &type)
166 {
167 SignonDisposable::destroyUnused();
168
169 AccessControlManagerHelper *acm = AccessControlManagerHelper::instance();
170 QDBusMessage msg = parentDBusContext().message();
171 QDBusConnection conn = parentDBusContext().connection();
172
173 /* Access Control */
174 if (id != SIGNOND_NEW_IDENTITY) {
175 if (!acm->isPeerAllowedToUseAuthSession(conn, msg, id)) {
176 SignOn::AccessReply *reply =
177 acm->requestAccessToIdentity(conn, msg, id);
178 /* If the request is accepted, we'll need the method name ("type")
179 * in order to proceed with the creation of the authsession. */
180 reply->setProperty("type", type);
181 QObject::connect(reply, SIGNAL(finished()),
182 this, SLOT(onAuthSessionAccessReplyFinished()));
183 msg.setDelayedReply(true);
184 return QString();
185 }
186 }
187
188 TRACE() << "ACM passed, creating AuthSession object";
189 pid_t ownerPid = acm->pidOfPeer(conn, msg);
190 QObject *authSession = m_parent->getAuthSession(id, type, ownerPid);
191 if (handleLastError(conn, msg)) return QString();
192
193 QDBusObjectPath objectPath = registerObject(conn, authSession);
194 return objectPath.path();
195 }
196
197 void SignonDaemonAdaptor::onAuthSessionAccessReplyFinished()
198 {
199 SignOn::AccessReply *reply = qobject_cast<SignOn::AccessReply*>(sender());
200 Q_ASSERT(reply != 0);
201
202 reply->deleteLater();
203 QDBusConnection connection = reply->request().peerConnection();
204 QDBusMessage message = reply->request().peerMessage();
205 quint32 id = reply->request().identity();
206 QString type = reply->property("type").toString();
207 AccessControlManagerHelper *acm = AccessControlManagerHelper::instance();
208
209 if (!reply->isAccepted() ||
210 !acm->isPeerAllowedToUseIdentity(connection, message, id)) {
211 securityErrorReply(connection, message);
212 TRACE() << "still not allowed";
213 return;
214 }
215
216 pid_t ownerPid = acm->pidOfPeer(connection, message);
217 QObject *authSession = m_parent->getAuthSession(id, type, ownerPid);
218 if (handleLastError(connection, message)) return;
219 QDBusObjectPath objectPath = registerObject(connection, authSession);
220
221 QVariantList args;
222 args << QVariant::fromValue(objectPath);
223 connection.send(message.createReply(args));
224
225 SignonDisposable::destroyUnused();
226 }
227
228 QStringList SignonDaemonAdaptor::queryMechanisms(const QString &method)
229 {
230 QStringList mechanisms = m_parent->queryMechanisms(method);
231 if (handleLastError(parentDBusContext().connection(),
232 parentDBusContext().message())) {
233 return QStringList();
234 }
235
236 return mechanisms;
237 }
238
239 void SignonDaemonAdaptor::queryIdentities(const QVariantMap &filter)
240 {
241 /* Access Control */
242 QDBusMessage msg = parentDBusContext().message();
243 QDBusConnection conn = parentDBusContext().connection();
244 if (!AccessControlManagerHelper::instance()->isPeerKeychainWidget(conn,
245 msg)) {
246 securityErrorReply();
247 return;
248 }
249
250 msg.setDelayedReply(true);
251 MapList identities = m_parent->queryIdentities(filter);
252 if (handleLastError(conn, msg)) return;
253
254 QDBusMessage reply = msg.createReply(QVariant::fromValue(identities));
255 conn.send(reply);
256 }
257
258 bool SignonDaemonAdaptor::clear()
259 {
260 /* Access Control */
261 QDBusMessage msg = parentDBusContext().message();
262 QDBusConnection conn = parentDBusContext().connection();
263 if (!AccessControlManagerHelper::instance()->isPeerKeychainWidget(conn,
264 msg)) {
265 securityErrorReply();
266 return false;
267 }
268
269 bool ok = m_parent->clear();
270 if (handleLastError(conn, msg)) return false;
271
272 return ok;
273 }
274
275 } //namespace SignonDaemonNS
SignonDaemonNS::SignonDaemon::queryIdentities
QList< QVariantMap > queryIdentities(const QVariantMap &filter)
Definition: signondaemon.cpp:705
SignonDaemonNS::SignonDaemonAdaptor::clear
bool clear()
Definition: signondaemonadaptor.cpp:258
SignonDaemonNS::SignonDaemonAdaptor::registerNewIdentity
void registerNewIdentity(QDBusObjectPath &objectPath)
Definition: signondaemonadaptor.cpp:44
SignonDaemonNS::SignonDaemonAdaptor::queryMethods
QStringList queryMethods()
Definition: signondaemonadaptor.cpp:159
BLAME
#define BLAME()
Definition: debug.h:32
SignonDaemonNS::AccessControlManagerHelper::instance
static AccessControlManagerHelper * instance()
Definition: accesscontrolmanagerhelper.cpp:44
SignonDaemonNS::SignonDaemonAdaptor::queryMechanisms
QStringList queryMechanisms(const QString &method)
Definition: signondaemonadaptor.cpp:228
SignonDaemonNS::SignonDaemon::registerNewIdentity
QObject * registerNewIdentity()
Definition: signondaemon.cpp:588
SignonDaemonNS::SignonDaemonAdaptor::getIdentity
void getIdentity(const quint32 id, QDBusObjectPath &objectPath, QVariantMap &identityData)
Definition: signondaemonadaptor.cpp:104
SignonDaemonNS::SignonDaemon::getIdentity
QObject * getIdentity(const quint32 id, QVariantMap &identityData)
Definition: signondaemon.cpp:617
SignonDaemonNS::SignonDisposable::destroyUnused
static void destroyUnused()
Deletes all disposable object for which the inactivity time has elapsed.
Definition: signondisposable.cpp:109
SignonDaemonNS::SignonDaemon::lastErrorIsValid
bool lastErrorIsValid() const
Definition: signondaemon.h:138
SignonDaemonNS::SignonDaemon::lastErrorMessage
QString lastErrorMessage() const
Definition: signondaemon.h:137
SignonDaemonNS::SignonDaemonAdaptor::queryIdentities
void queryIdentities(const QVariantMap &filter)
Definition: signondaemonadaptor.cpp:239
SignonDaemonNS::SignonDaemonAdaptor::getAuthSessionObjectPath
QString getAuthSessionObjectPath(const quint32 id, const QString &type)
Definition: signondaemonadaptor.cpp:164
signondaemonadaptor.h
SignonDaemonNS::SignonDaemon::getAuthSession
QObject * getAuthSession(const quint32 id, const QString type, pid_t ownerPid)
Definition: signondaemon.cpp:764
SignonDaemonNS::AccessControlManagerHelper::requestAccessToIdentity
SignOn::AccessReply * requestAccessToIdentity(const QDBusConnection &peerConnection, const QDBusMessage &peerMessage, quint32 id)
Definition: accesscontrolmanagerhelper.cpp:205
SignonDaemonNS::AccessControlManagerHelper::pidOfPeer
static pid_t pidOfPeer(const QDBusContext &peerContext)
Definition: accesscontrolmanagerhelper.cpp:173
SignonDaemonNS::SignonDaemon::clear
bool clear()
Definition: signondaemon.cpp:742
SignonDaemonNS::AccessControlManagerHelper::isPeerAllowedToUseAuthSession
bool isPeerAllowedToUseAuthSession(const QDBusConnection &peerConnection, const QDBusMessage &peerMessage, const SignonAuthSession &authSession)
Checks if a specific process is allowed to use the SignonAuthSession functionality.
Definition: accesscontrolmanagerhelper.h:114
TRACE
#define TRACE()
Definition: debug.h:28
accesscontrolmanagerhelper.h
Helper class for access control-related functionality.
SignonDaemonNS::AccessControlManagerHelper
Contains helper functions related to Access Control.
Definition: accesscontrolmanagerhelper.h:51
SignonDaemonNS::SignonDaemon::queryMethods
QStringList queryMethods()
Definition: signondaemon.cpp:654
SignonDaemonNS::SignonDaemon::queryMechanisms
QStringList queryMechanisms(const QString &method)
Definition: signondaemon.cpp:676
signondisposable.h
SignonDaemonNS::SignonDaemon::lastErrorName
QString lastErrorName() const
Definition: signondaemon.h:136
QList
Definition: backupifadaptor.h:18
SignonDaemonNS::AccessControlManagerHelper::isPeerAllowedToUseIdentity
bool isPeerAllowedToUseIdentity(const QDBusConnection &peerConnection, const QDBusMessage &peerMessage, const quint32 identityId)
Checks if a client process is allowed to use a specific SignonIdentity.
Definition: accesscontrolmanagerhelper.cpp:67