Plasma
authorizationmanager.cpp
Go to the documentation of this file.
00001 /* 00002 * Copyright 2009 by Rob Scheepmaker <r.scheepmaker@student.utwente.nl> 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, 00017 * Boston, MA 02110-1301 USA 00018 */ 00019 00020 #include "authorizationmanager.h" 00021 #include "private/authorizationmanager_p.h" 00022 00023 #include "authorizationinterface.h" 00024 #include "authorizationrule.h" 00025 #include "credentials.h" 00026 #include "service.h" 00027 #include "servicejob.h" 00028 00029 #include "private/authorizationrule_p.h" 00030 #include "private/denyallauthorization_p.h" 00031 #include "private/joliemessagehelper_p.h" 00032 #include "private/pinpairingauthorization_p.h" 00033 #include "private/trustedonlyauthorization_p.h" 00034 00035 #include <QtCore/QBuffer> 00036 #include <QtCore/QMap> 00037 #include <QtCore/QMetaType> 00038 #include <QtCore/QTimer> 00039 00040 #include <QtNetwork/QHostInfo> 00041 00042 #include <QtJolie/Message> 00043 #include <QtJolie/Server> 00044 00045 #include <kauthaction.h> 00046 #include <kconfiggroup.h> 00047 #include <kdebug.h> 00048 #include <kstandarddirs.h> 00049 #include <ktemporaryfile.h> 00050 #include <kurl.h> 00051 #include <kwallet.h> 00052 00053 namespace Plasma 00054 { 00055 00056 class AuthorizationManagerSingleton 00057 { 00058 public: 00059 AuthorizationManager self; 00060 }; 00061 00062 K_GLOBAL_STATIC(AuthorizationManagerSingleton, privateAuthorizationManagerSelf) 00063 00064 AuthorizationManager *AuthorizationManager::self() 00065 { 00066 return &privateAuthorizationManagerSelf->self; 00067 } 00068 00069 AuthorizationManager::AuthorizationManager() 00070 : QObject(), 00071 d(new AuthorizationManagerPrivate(this)) 00072 { 00073 qRegisterMetaTypeStreamOperators<Plasma::Credentials>("Plasma::Credentials"); 00074 } 00075 00076 AuthorizationManager::~AuthorizationManager() 00077 { 00078 delete d; 00079 } 00080 00081 void AuthorizationManager::setAuthorizationPolicy(AuthorizationPolicy policy) 00082 { 00083 if (d->locked) { 00084 kDebug() << "Can't change AuthorizationPolicy: interface locked."; 00085 return; 00086 } 00087 00088 if (policy == d->authorizationPolicy) { 00089 return; 00090 } 00091 00092 d->authorizationPolicy = policy; 00093 00094 if (d->authorizationInterface != d->customAuthorizationInterface) { 00095 delete d->authorizationInterface; 00096 } 00097 00098 switch (policy) { 00099 case DenyAll: 00100 d->authorizationInterface = new DenyAllAuthorization(); 00101 break; 00102 case PinPairing: 00103 d->authorizationInterface = new PinPairingAuthorization(); 00104 break; 00105 case TrustedOnly: 00106 d->authorizationInterface = new TrustedOnlyAuthorization(); 00107 break; 00108 case Custom: 00109 d->authorizationInterface = d->customAuthorizationInterface; 00110 break; 00111 } 00112 00113 d->locked = true; 00114 } 00115 00116 void AuthorizationManager::setAuthorizationInterface(AuthorizationInterface *interface) 00117 { 00118 if (d->authorizationInterface) { 00119 kDebug() << "Can't change AuthorizationInterface: interface locked."; 00120 return; 00121 } 00122 00123 delete d->customAuthorizationInterface; 00124 d->customAuthorizationInterface = interface; 00125 00126 if (d->authorizationPolicy == Custom) { 00127 d->authorizationInterface = interface; 00128 } 00129 } 00130 00131 AuthorizationManagerPrivate::AuthorizationManagerPrivate(AuthorizationManager *manager) 00132 : q(manager), 00133 server(0), 00134 authorizationPolicy(AuthorizationManager::DenyAll), 00135 authorizationInterface(new DenyAllAuthorization()), 00136 customAuthorizationInterface(0), 00137 rulesConfig(KSharedConfig::openConfig("/etc/plasma-remotewidgets.conf")->group("Rules")), 00138 locked(false) 00139 { 00140 } 00141 00142 AuthorizationManagerPrivate::~AuthorizationManagerPrivate() 00143 { 00144 delete authorizationInterface; 00145 delete customAuthorizationInterface; 00146 delete server; 00147 } 00148 00149 void AuthorizationManagerPrivate::prepareForServiceAccess() 00150 { 00151 if (myCredentials.isValid()) { 00152 return; 00153 } 00154 00155 wallet = KWallet::Wallet::openWallet("kdewallet", 0, KWallet::Wallet::Asynchronous); 00156 q->connect(wallet, SIGNAL(walletOpened(bool)), q, SLOT(slotWalletOpened())); 00157 QTimer::singleShot(0, q, SLOT(slotLoadRules())); 00158 } 00159 00160 void AuthorizationManagerPrivate::prepareForServicePublication() 00161 { 00162 if (!server) { 00163 server = new Jolie::Server(4000); 00164 } 00165 } 00166 00167 void AuthorizationManagerPrivate::saveRules() 00168 { 00169 kDebug() << "SAVE RULES"; 00170 00171 KTemporaryFile tempFile; 00172 tempFile.open(); 00173 tempFile.setAutoRemove(false); 00174 KConfigGroup rulesGroup = KSharedConfig::openConfig(tempFile.fileName())->group("Rules"); 00175 00176 int i = 0; 00177 foreach (AuthorizationRule *rule, rules) { 00178 if (rule->persistence() == AuthorizationRule::Persistent) { 00179 kDebug() << "adding rule " << i; 00180 rulesGroup.group(QString::number(i)).writeEntry("CredentialsID", rule->credentials().id()); 00181 rulesGroup.group(QString::number(i)).writeEntry("serviceName", rule->serviceName()); 00182 rulesGroup.group(QString::number(i)).writeEntry("Policy", (uint)rule->policy()); 00183 rulesGroup.group(QString::number(i)).writeEntry("Targets", (uint)rule->targets()); 00184 rulesGroup.group(QString::number(i)).writeEntry("Persistence", (uint)rule->persistence()); 00185 i++; 00186 } 00187 } 00188 rulesGroup.sync(); 00189 tempFile.close(); 00190 00191 kDebug() << "tempfile = " << tempFile.fileName(); 00192 00193 KAuth::Action action("org.kde.kcontrol.kcmremotewidgets.save"); 00194 action.addArgument("source", tempFile.fileName()); 00195 action.addArgument("filename", "/etc/plasma-remotewidgets.conf"); 00196 KAuth::ActionReply reply = action.execute(); 00197 00198 if (reply.failed()) { 00199 kDebug() << "KAuth failed.... YOU SUCK!"; 00200 } 00201 } 00202 00203 void AuthorizationManagerPrivate::slotWalletOpened() 00204 { 00205 QByteArray identity; 00206 00207 if (!wallet->readEntry("Credentials", identity)) { 00208 kDebug() << "Existing identity found"; 00209 QDataStream stream(&identity, QIODevice::ReadOnly); 00210 stream >> myCredentials; 00211 } 00212 00213 if (!myCredentials.isValid()) { 00214 kDebug() << "Creating a new identity"; 00215 myCredentials = Credentials::createCredentials(QHostInfo::localHostName()); 00216 QDataStream stream(&identity, QIODevice::WriteOnly); 00217 stream << myCredentials; 00218 wallet->writeEntry("Credentials", identity); 00219 } 00220 00221 emit q->readyForRemoteAccess(); 00222 } 00223 00224 void AuthorizationManagerPrivate::slotLoadRules() 00225 { 00226 foreach (const QString &groupName, rulesConfig.groupList()) { 00227 QString identityID = rulesConfig.group(groupName).readEntry("CredentialsID", ""); 00228 QString serviceName = rulesConfig.group(groupName).readEntry("serviceName", ""); 00229 uint policy = rulesConfig.group(groupName).readEntry("Policy", 0); 00230 uint targets = rulesConfig.group(groupName).readEntry("Targets", 0); 00231 uint persistence = rulesConfig.group(groupName).readEntry("Persistence", 0); 00232 //Credentials storedCredentials = identities[identityID]; 00233 if (serviceName.isEmpty()) { 00234 kDebug() << "Invalid rule"; 00235 } else { 00236 AuthorizationRule *rule = new AuthorizationRule(serviceName, identityID); 00237 rule->setPolicy(static_cast<AuthorizationRule::Policy>(policy)); 00238 rule->setTargets(static_cast<AuthorizationRule::Targets>(targets)); 00239 rule->setPersistence(static_cast<AuthorizationRule::Persistence>(persistence)); 00240 rules.append(rule); 00241 } 00242 } 00243 } 00244 00245 AuthorizationRule *AuthorizationManagerPrivate::matchingRule(const QString &serviceName, 00246 const Credentials &identity) const 00247 { 00248 AuthorizationRule *matchingRule = 0; 00249 foreach (AuthorizationRule *rule, rules) { 00250 if (rule->d->matches(serviceName, identity.id())) { 00251 //a message can have multiple matching rules, consider priorities: the more specific the 00252 //rule is, the higher it's priority 00253 if (!matchingRule) { 00254 matchingRule = rule; 00255 } else { 00256 if (!matchingRule->targets().testFlag(AuthorizationRule::AllServices) && 00257 !matchingRule->targets().testFlag(AuthorizationRule::AllUsers)) { 00258 matchingRule = rule; 00259 } 00260 } 00261 } 00262 } 00263 00264 if (!matchingRule) { 00265 kDebug() << "no matching rule"; 00266 } else { 00267 kDebug() << "matching rule found: " << matchingRule->description(); 00268 } 00269 return matchingRule; 00270 } 00271 00272 Credentials AuthorizationManagerPrivate::getCredentials(const QString &id) 00273 { 00274 if (identities.contains(id)) { 00275 return identities[id]; 00276 } else { 00277 return Credentials(); 00278 } 00279 } 00280 00281 void AuthorizationManagerPrivate::addCredentials(const Credentials &identity) 00282 { 00283 if (identities.contains(identity.id())) { 00284 return; 00285 } else if (identity.isValid()) { 00286 kDebug() << "Adding a new identity for " << identity.id(); 00287 identities[identity.id()] = identity; 00288 } 00289 } 00290 00291 } // Plasma namespace 00292 00293 #include "authorizationmanager.moc"
KDE 4.6 API Reference