signon  8.58
accesscontrolmanagerhelper.cpp
Go to the documentation of this file.
1 /* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of signon
4  *
5  * Copyright (C) 2009-2010 Nokia Corporation.
6  * Copyright (C) 2011 Intel Corporation.
7  * Copyright (C) 2013 Canonical Ltd.
8  *
9  * Contact: Aurel Popirtac <ext-aurel.popirtac@nokia.com>
10  * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
11  * Contact: Elena Reshetova <elena.reshetova@intel.com>
12  *
13  * This library is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU Lesser General Public License
15  * version 2.1 as published by the Free Software Foundation.
16  *
17  * This library is distributed in the hope that it will be useful, but
18  * WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with this library; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25  * 02110-1301 USA
26  */
27 
28 #include <QBuffer>
29 #include <QDBusConnection>
30 #include <QDBusConnectionInterface>
31 #ifdef ENABLE_P2P
32 #include <dbus/dbus.h>
33 #endif
34 
36 #include "signond-common.h"
38 #include "signonidentity.h"
39 
40 using namespace SignonDaemonNS;
41 
42 AccessControlManagerHelper *AccessControlManagerHelper::m_pInstance = NULL;
43 
45 {
46  return m_pInstance;
47 }
48 
50  SignOn::AbstractAccessControlManager *acManager)
51 {
52  if (!m_pInstance) {
53  m_pInstance = this;
54  m_acManager = acManager;
55  } else {
56  BLAME() << "Creating a second instance of the CAM";
57  }
58 }
59 
61 {
62  m_acManager = NULL;
63  m_pInstance = NULL;
64 }
65 
66 
68  const QDBusConnection &peerConnection,
69  const QDBusMessage &peerMessage,
70  const quint32 identityId)
71 {
72  // TODO - improve this, the error handling and more precise behaviour
73 
75  if (db == 0) {
76  TRACE() << "NULL db pointer, secure storage might be unavailable,";
77  return false;
78  }
79  QStringList acl = db->accessControlList(identityId);
80 
81  TRACE() << QString(QLatin1String("Access control list of identity: "
82  "%1: [%2].Tokens count: %3\t"))
83  .arg(identityId)
84  .arg(acl.join(QLatin1String(", ")))
85  .arg(acl.size());
86 
87  if (db->errorOccurred())
88  return false;
89 
90  IdentityOwnership ownership =
91  isPeerOwnerOfIdentity(peerConnection, peerMessage, identityId);
92  if (ownership == ApplicationIsOwner)
93  return true;
94 
95  if (acl.isEmpty())
96  return false;
97 
98  if (acl.contains(QLatin1String("*")))
99  return true;
100 
101  return peerHasOneOfAccesses(peerConnection, peerMessage, acl);
102 }
103 
106  const QDBusConnection &peerConnection,
107  const QDBusMessage &peerMessage,
108  const quint32 identityId)
109 {
111  if (db == 0) {
112  TRACE() << "NULL db pointer, secure storage might be unavailable,";
113  return ApplicationIsNotOwner;
114  }
115  QStringList ownerSecContexts = db->ownerList(identityId);
116 
117  if (db->errorOccurred())
118  return ApplicationIsNotOwner;
119 
120  if (ownerSecContexts.isEmpty())
122 
123  return peerHasOneOfAccesses(peerConnection, peerMessage, ownerSecContexts) ?
125 }
126 
127 bool
129  const QDBusConnection &peerConnection,
130  const QDBusMessage &peerMessage)
131 {
132  static QString keychainWidgetAppId = m_acManager->keychainWidgetAppId();
133  QString peerAppId = appIdOfPeer(peerConnection, peerMessage);
134  return (peerAppId == keychainWidgetAppId);
135 }
136 
138  const QDBusConnection &peerConnection,
139  const QDBusMessage &peerMessage)
140 {
141  TRACE() << m_acManager->appIdOfPeer(peerConnection, peerMessage);
142  return m_acManager->appIdOfPeer(peerConnection, peerMessage);
143 }
144 
145 bool
147  const QDBusConnection &peerConnection,
148  const QDBusMessage &peerMessage,
149  const QStringList secContexts)
150 {
151  foreach(QString securityContext, secContexts)
152  {
153  TRACE() << securityContext;
154  if (isPeerAllowedToAccess(peerConnection, peerMessage, securityContext))
155  return true;
156  }
157 
158  BLAME() << "given peer does not have needed permissions";
159  return false;
160 }
161 
162 bool
164  const QDBusConnection &peerConnection,
165  const QDBusMessage &peerMessage,
166  const QString securityContext)
167 {
168  TRACE() << securityContext;
169  return m_acManager->isPeerAllowedToAccess(peerConnection, peerMessage,
170  securityContext);
171 }
172 
173 pid_t AccessControlManagerHelper::pidOfPeer(const QDBusContext &peerContext)
174 {
175  return pidOfPeer(peerContext.connection(), peerContext.message());
176 }
177 
179  const QDBusConnection &peerConnection,
180  const QDBusMessage &peerMessage)
181 {
182  QString service = peerMessage.service();
183  if (service.isEmpty()) {
184 #ifdef ENABLE_P2P
185  DBusConnection *connection =
186  (DBusConnection *)peerConnection.internalPointer();
187  unsigned long pid = 0;
188  dbus_bool_t ok = dbus_connection_get_unix_process_id(connection,
189  &pid);
190  if (Q_UNLIKELY(!ok)) {
191  BLAME() << "Couldn't get PID of caller!";
192  return 0;
193  }
194  return pid;
195 #else
196  BLAME() << "Empty caller name, and no P2P support enabled";
197  return 0;
198 #endif
199  } else {
200  return peerConnection.interface()->servicePid(service).value();
201  }
202 }
203 
204 SignOn::AccessReply *
206  const QDBusConnection &peerConnection,
207  const QDBusMessage &peerMessage,
208  quint32 id)
209 {
210  SignOn::AccessRequest request;
211  request.setPeer(peerConnection, peerMessage);
212  request.setIdentity(id);
213  return m_acManager->handleRequest(request);
214 }
bool peerHasOneOfAccesses(const QDBusConnection &peerConnection, const QDBusMessage &peerMessage, const QStringList secContexts)
Checks if a client process is allowed to access at least one object from the list with a certain secu...
QString appIdOfPeer(const QDBusConnection &peerConnection, const QDBusMessage &peerMessage)
Looks up for the application identifier of a specific client process.
QStringList accessControlList(const quint32 identityId)
#define BLAME()
Definition: debug.h:32
static AccessControlManagerHelper * instance()
bool isPeerKeychainWidget(const QDBusConnection &peerConnection, const QDBusMessage &peerMessage)
AccessControlManagerHelper(SignOn::AbstractAccessControlManager *acManager)
static CredentialsAccessManager * instance()
Returns CAM instance.
SignOn::AccessReply * requestAccessToIdentity(const QDBusConnection &peerConnection, const QDBusMessage &peerMessage, quint32 id)
static pid_t pidOfPeer(const QDBusContext &peerContext)
Definition of the CredentialsAccessManager object.
IdentityOwnership
Specifies the owner relationship of an application over a specific identity, or the lack of ownership...
#define TRACE()
Definition: debug.h:28
IdentityOwnership isPeerOwnerOfIdentity(const QDBusConnection &peerConnection, const QDBusMessage &peerMessage, const quint32 identityId)
Checks if a specific process is the owner of a SignonIdentity, thus having full control over it...
Manages the credentials I/O.
Definition: credentialsdb.h:66
bool isPeerAllowedToAccess(const QDBusConnection &peerConnection, const QDBusMessage &peerMessage, const QString securityContext)
Checks if a client process is allowed to access objects with a certain security context.
QStringList ownerList(const quint32 identityId)
Helper class for access control-related functionality.
Contains helper functions related to Access Control.
bool isPeerAllowedToUseIdentity(const QDBusConnection &peerConnection, const QDBusMessage &peerMessage, const quint32 identityId)
Checks if a client process is allowed to use a specific SignonIdentity.