signon  8.40
accesscontrolmanagerhelper.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /*
00003  * This file is part of signon
00004  *
00005  * Copyright (C) 2009-2010 Nokia Corporation.
00006  * Copyright (C) 2011 Intel Corporation.
00007  *
00008  * Contact: Aurel Popirtac <ext-aurel.popirtac@nokia.com>
00009  * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
00010  * Contact: Elena Reshetova <elena.reshetova@intel.com>
00011  *
00012  * This library is free software; you can redistribute it and/or
00013  * modify it under the terms of the GNU Lesser General Public License
00014  * version 2.1 as published by the Free Software Foundation.
00015  *
00016  * This library is distributed in the hope that it will be useful, but
00017  * WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00019  * Lesser General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Lesser General Public
00022  * License along with this library; if not, write to the Free Software
00023  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00024  * 02110-1301 USA
00025  */
00026 
00027 #include <QBuffer>
00028 #include <QDBusConnection>
00029 #include <QDBusConnectionInterface>
00030 
00031 #include "accesscontrolmanagerhelper.h"
00032 #include "signond-common.h"
00033 #include "credentialsaccessmanager.h"
00034 #include "signonidentity.h"
00035 
00036 using namespace SignonDaemonNS;
00037 
00038 AccessControlManagerHelper *AccessControlManagerHelper::m_pInstance = NULL;
00039 
00040 AccessControlManagerHelper *AccessControlManagerHelper::instance()
00041 {
00042     return m_pInstance;
00043 }
00044 
00045 AccessControlManagerHelper::AccessControlManagerHelper(
00046                                 SignOn::AbstractAccessControlManager *acManager)
00047 {
00048     if (!m_pInstance) {
00049         m_pInstance = this;
00050         m_acManager = acManager;
00051     } else {
00052         BLAME() << "Creating a second instance of the CAM";
00053     }
00054 }
00055 
00056 AccessControlManagerHelper::~AccessControlManagerHelper()
00057 {
00058     m_acManager = NULL;
00059     m_pInstance = NULL;
00060 }
00061 
00062 
00063 bool
00064 AccessControlManagerHelper::isPeerAllowedToUseIdentity(
00065                                                const QDBusMessage &peerMessage,
00066                                                const quint32 identityId)
00067 {
00068     // TODO - improve this, the error handling and more precise behaviour
00069 
00070     CredentialsDB *db = CredentialsAccessManager::instance()->credentialsDB();
00071     if (db == 0) {
00072         TRACE() << "NULL db pointer, secure storage might be unavailable,";
00073         return false;
00074     }
00075     QStringList acl = db->accessControlList(identityId);
00076 
00077     TRACE() << QString(QLatin1String("Access control list of identity: "
00078                                  "%1: [%2].Tokens count: %3\t"))
00079                                 .arg(identityId)
00080                                 .arg(acl.join(QLatin1String(", ")))
00081                                 .arg(acl.size());
00082 
00083     if (db->errorOccurred())
00084         return false;
00085 
00086     if (acl.isEmpty())
00087         return true;
00088 
00089     return peerHasOneOfAccesses(peerMessage, acl);
00090 }
00091 
00092 AccessControlManagerHelper::IdentityOwnership
00093 AccessControlManagerHelper::isPeerOwnerOfIdentity(
00094                                                const QDBusMessage &peerMessage,
00095                                                const quint32 identityId)
00096 {
00097     CredentialsDB *db = CredentialsAccessManager::instance()->credentialsDB();
00098     if (db == 0) {
00099         TRACE() << "NULL db pointer, secure storage might be unavailable,";
00100         return ApplicationIsNotOwner;
00101     }
00102     QStringList ownerSecContexts = db->ownerList(identityId);
00103 
00104     if (db->errorOccurred())
00105         return ApplicationIsNotOwner;
00106 
00107     if (ownerSecContexts.isEmpty())
00108         return IdentityDoesNotHaveOwner;
00109 
00110     return peerHasOneOfAccesses(peerMessage, ownerSecContexts) ?
00111         ApplicationIsOwner : ApplicationIsNotOwner;
00112 }
00113 
00114 bool
00115 AccessControlManagerHelper::isPeerKeychainWidget(const QDBusMessage &peerMessage)
00116 {
00117     static QString keychainWidgetAppId = m_acManager->keychainWidgetAppId();
00118     QString peerAppId = m_acManager->appIdOfPeer(peerMessage);
00119     return (peerAppId == keychainWidgetAppId);
00120 }
00121 
00122 QString AccessControlManagerHelper::appIdOfPeer(const QDBusMessage &peerMessage)
00123 {
00124     TRACE() << m_acManager->appIdOfPeer(peerMessage);
00125     return m_acManager->appIdOfPeer(peerMessage);
00126 }
00127 
00128 bool
00129 AccessControlManagerHelper::peerHasOneOfAccesses(const QDBusMessage &peerMessage,
00130                                                  const QStringList secContexts)
00131 {
00132     foreach(QString securityContext, secContexts)
00133     {
00134         TRACE() << securityContext;
00135         if (m_acManager->isPeerAllowedToAccess(peerMessage, securityContext))
00136             return true;
00137     }
00138 
00139     BLAME() << "given peer does not have needed permissions";
00140     return false;
00141 }
00142 
00143 bool
00144 AccessControlManagerHelper::isPeerAllowedToAccess(
00145                                                const QDBusMessage &peerMessage,
00146                                                const QString securityContext)
00147 {
00148     TRACE() << securityContext;
00149     return m_acManager->isPeerAllowedToAccess(peerMessage, securityContext);
00150 }
00151 
00152 pid_t AccessControlManagerHelper::pidOfPeer(const QDBusContext &peerContext)
00153 {
00154     QString service = peerContext.message().service();
00155     return peerContext.connection().interface()->servicePid(service).value();
00156 }
00157