|
signon
8.40
|
00001 /* 00002 * This file is part of signon 00003 * 00004 * Copyright (C) 2009-2010 Nokia Corporation. 00005 * Copyright (C) 2011 Intel Corporation. 00006 * 00007 * Contact: Aurel Popirtac <ext-aurel.popirtac@nokia.com> 00008 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com> 00009 * Contact: Jussi Laako <jussi.laako@linux.intel.com> 00010 * 00011 * This library is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU Lesser General Public License 00013 * version 2.1 as published by the Free Software Foundation. 00014 * 00015 * This library is distributed in the hope that it will be useful, but 00016 * WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 * Lesser General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU Lesser General Public 00021 * License along with this library; if not, write to the Free Software 00022 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 00023 * 02110-1301 USA 00024 */ 00025 00026 #include <iostream> 00027 #include <QVariantMap> 00028 00029 #include "signond-common.h" 00030 #include "signonidentity.h" 00031 #include "signonui_interface.h" 00032 #include "SignOn/uisessiondata.h" 00033 #include "SignOn/uisessiondata_priv.h" 00034 #include "signoncommon.h" 00035 00036 #include "accesscontrolmanagerhelper.h" 00037 #include "signonidentityadaptor.h" 00038 00039 #define SIGNON_RETURN_IF_CAM_UNAVAILABLE(_ret_arg_) do { \ 00040 if (!(CredentialsAccessManager::instance()->credentialsSystemOpened())) { \ 00041 sendErrorReply(internalServerErrName, \ 00042 internalServerErrStr + \ 00043 QLatin1String("Could not access Signon Database."));\ 00044 return _ret_arg_; \ 00045 } \ 00046 } while(0) 00047 00048 namespace SignonDaemonNS { 00049 00050 const QString internalServerErrName = SIGNOND_INTERNAL_SERVER_ERR_NAME; 00051 const QString internalServerErrStr = SIGNOND_INTERNAL_SERVER_ERR_STR; 00052 00053 SignonIdentity::SignonIdentity(quint32 id, int timeout, 00054 SignonDaemon *parent): 00055 SignonDisposable(timeout, parent), 00056 m_pInfo(NULL), 00057 m_pSignonDaemon(parent), 00058 m_registered(false) 00059 { 00060 m_id = id; 00061 00062 /* 00063 * creation of unique name for the given identity 00064 * */ 00065 static quint32 incr = 0; 00066 QString objectName = SIGNOND_DAEMON_OBJECTPATH + QLatin1String("/Identity_") 00067 + QString::number(incr++, 16); 00068 setObjectName(objectName); 00069 00070 m_signonui = new SignonUiAdaptor( 00071 SIGNON_UI_SERVICE, 00072 SIGNON_UI_DAEMON_OBJECTPATH, 00073 SIGNOND_BUS, 00074 this); 00075 } 00076 00077 SignonIdentity::~SignonIdentity() 00078 { 00079 if (m_registered) 00080 { 00081 emit unregistered(); 00082 QDBusConnection connection = SIGNOND_BUS; 00083 connection.unregisterObject(objectName()); 00084 } 00085 00086 if (credentialsStored()) 00087 m_pSignonDaemon->m_storedIdentities.remove(m_id); 00088 else 00089 m_pSignonDaemon->m_unstoredIdentities.remove(objectName()); 00090 00091 delete m_signonui; 00092 } 00093 00094 bool SignonIdentity::init() 00095 { 00096 QDBusConnection connection = SIGNOND_BUS; 00097 00098 if (!connection.isConnected()) { 00099 QDBusError err = connection.lastError(); 00100 TRACE() << "Connection cannot be established:" << 00101 err.errorString(err.type()) ; 00102 return false; 00103 } 00104 00105 QDBusConnection::RegisterOptions registerOptions = 00106 QDBusConnection::ExportAllContents; 00107 00108 (void)new SignonIdentityAdaptor(this); 00109 registerOptions = QDBusConnection::ExportAdaptors; 00110 00111 if (!connection.registerObject(objectName(), this, registerOptions)) { 00112 TRACE() << "Object cannot be registered: " << objectName(); 00113 return false; 00114 } 00115 00116 return (m_registered = true); 00117 } 00118 00119 SignonIdentity *SignonIdentity::createIdentity(quint32 id, SignonDaemon *parent) 00120 { 00121 SignonIdentity *identity = 00122 new SignonIdentity(id, parent->identityTimeout(), parent); 00123 00124 if (!identity->init()) { 00125 TRACE() << "The created identity is invalid and will be deleted.\n"; 00126 delete identity; 00127 return NULL; 00128 } 00129 00130 return identity; 00131 } 00132 00133 void SignonIdentity::destroy() 00134 { 00135 if (m_registered) 00136 { 00137 emit unregistered(); 00138 QDBusConnection connection = SIGNOND_BUS; 00139 connection.unregisterObject(objectName()); 00140 m_registered = false; 00141 } 00142 00143 deleteLater(); 00144 } 00145 00146 SignonIdentityInfo SignonIdentity::queryInfo(bool &ok, bool queryPassword) 00147 { 00148 ok = true; 00149 00150 bool needLoadFromDB = true; 00151 if (m_pInfo) { 00152 needLoadFromDB = false; 00153 if (queryPassword && m_pInfo->password().isEmpty()) { 00154 needLoadFromDB = true; 00155 } 00156 } 00157 00158 if (needLoadFromDB) { 00159 if (m_pInfo != 0) { 00160 delete m_pInfo; 00161 } 00162 00163 CredentialsDB *db = 00164 CredentialsAccessManager::instance()->credentialsDB(); 00165 m_pInfo = new SignonIdentityInfo(db->credentials(m_id, queryPassword)); 00166 00167 if (db->lastError().isValid()) { 00168 ok = false; 00169 delete m_pInfo; 00170 m_pInfo = NULL; 00171 return SignonIdentityInfo(); 00172 } 00173 } 00174 00175 /* Make sure that we clear the password, if the caller doesn't need it */ 00176 SignonIdentityInfo info = *m_pInfo; 00177 if (!queryPassword) { 00178 info.setPassword(QString()); 00179 } 00180 return info; 00181 } 00182 00183 bool SignonIdentity::addReference(const QString &reference) 00184 { 00185 TRACE() << "addReference: " << reference; 00186 00187 SIGNON_RETURN_IF_CAM_UNAVAILABLE(false); 00188 00189 CredentialsDB *db = CredentialsAccessManager::instance()->credentialsDB(); 00190 if (db == NULL) { 00191 BLAME() << "NULL database handler object."; 00192 return false; 00193 } 00194 QString appId = 00195 AccessControlManagerHelper::instance()->appIdOfPeer( 00196 (static_cast<QDBusContext>(*this)).message()); 00197 keepInUse(); 00198 return db->addReference(m_id, appId, reference); 00199 } 00200 00201 bool SignonIdentity::removeReference(const QString &reference) 00202 { 00203 TRACE() << "removeReference: " << reference; 00204 00205 SIGNON_RETURN_IF_CAM_UNAVAILABLE(false); 00206 00207 CredentialsDB *db = CredentialsAccessManager::instance()->credentialsDB(); 00208 if (db == NULL) { 00209 BLAME() << "NULL database handler object."; 00210 return false; 00211 } 00212 QString appId = 00213 AccessControlManagerHelper::instance()->appIdOfPeer( 00214 (static_cast<QDBusContext>(*this)).message()); 00215 keepInUse(); 00216 return db->removeReference(m_id, appId, reference); 00217 } 00218 00219 quint32 SignonIdentity::requestCredentialsUpdate(const QString &displayMessage) 00220 { 00221 SIGNON_RETURN_IF_CAM_UNAVAILABLE(SIGNOND_NEW_IDENTITY); 00222 00223 bool ok; 00224 SignonIdentityInfo info = queryInfo(ok, false); 00225 00226 if (!ok) { 00227 BLAME() << "Identity not found."; 00228 sendErrorReply(SIGNOND_IDENTITY_NOT_FOUND_ERR_NAME, 00229 SIGNOND_IDENTITY_NOT_FOUND_ERR_STR); 00230 return SIGNOND_NEW_IDENTITY; 00231 } 00232 if (!info.storePassword()) { 00233 BLAME() << "Password cannot be stored."; 00234 sendErrorReply(SIGNOND_STORE_FAILED_ERR_NAME, 00235 SIGNOND_STORE_FAILED_ERR_STR); 00236 return SIGNOND_NEW_IDENTITY; 00237 } 00238 00239 //delay dbus reply, ui interaction might take long time to complete 00240 setDelayedReply(true); 00241 m_message = message(); 00242 00243 //create ui request to ask password 00244 QVariantMap uiRequest; 00245 uiRequest.insert(SSOUI_KEY_QUERYPASSWORD, true); 00246 uiRequest.insert(SSOUI_KEY_USERNAME, info.userName()); 00247 uiRequest.insert(SSOUI_KEY_MESSAGE, displayMessage); 00248 uiRequest.insert(SSOUI_KEY_CAPTION, info.caption()); 00249 00250 TRACE() << "Waiting for reply from signon-ui"; 00251 QDBusPendingCallWatcher *watcher = 00252 new QDBusPendingCallWatcher(m_signonui->queryDialog(uiRequest), this); 00253 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), 00254 this, SLOT(queryUiSlot(QDBusPendingCallWatcher*))); 00255 00256 setAutoDestruct(false); 00257 return 0; 00258 } 00259 00260 QVariantMap SignonIdentity::getInfo() 00261 { 00262 TRACE() << "QUERYING INFO"; 00263 00264 SIGNON_RETURN_IF_CAM_UNAVAILABLE(QVariantMap()); 00265 00266 bool ok; 00267 SignonIdentityInfo info = queryInfo(ok, false); 00268 00269 if (!ok) { 00270 TRACE(); 00271 sendErrorReply(SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_NAME, 00272 SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_STR + 00273 QLatin1String("Database querying error occurred.")); 00274 return QVariantMap(); 00275 } 00276 00277 if (info.isNew()) { 00278 TRACE(); 00279 sendErrorReply(SIGNOND_IDENTITY_NOT_FOUND_ERR_NAME, 00280 SIGNOND_IDENTITY_NOT_FOUND_ERR_STR); 00281 return QVariantMap(); 00282 } 00283 00284 keepInUse(); 00285 return info.toMap(); 00286 } 00287 00288 void SignonIdentity::queryUserPassword(const QVariantMap ¶ms) { 00289 TRACE() << "Waiting for reply from signon-ui"; 00290 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher( 00291 m_signonui->queryDialog(params), this); 00292 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, 00293 SLOT(verifyUiSlot(QDBusPendingCallWatcher*))); 00294 00295 setAutoDestruct(false); 00296 } 00297 00298 bool SignonIdentity::verifyUser(const QVariantMap ¶ms) 00299 { 00300 SIGNON_RETURN_IF_CAM_UNAVAILABLE(false); 00301 00302 bool ok; 00303 SignonIdentityInfo info = queryInfo(ok, true); 00304 00305 if (!ok) { 00306 BLAME() << "Identity not found."; 00307 sendErrorReply(SIGNOND_IDENTITY_NOT_FOUND_ERR_NAME, 00308 SIGNOND_IDENTITY_NOT_FOUND_ERR_STR); 00309 return false; 00310 } 00311 if (!info.storePassword() || info.password().isEmpty()) { 00312 BLAME() << "Password is not stored."; 00313 sendErrorReply(SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_NAME, 00314 SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_STR); 00315 return false; 00316 } 00317 00318 //delay dbus reply, ui interaction might take long time to complete 00319 setDelayedReply(true); 00320 m_message = message(); 00321 00322 //create ui request to ask password 00323 QVariantMap uiRequest; 00324 uiRequest.unite(params); 00325 uiRequest.insert(SSOUI_KEY_QUERYPASSWORD, true); 00326 uiRequest.insert(SSOUI_KEY_USERNAME, info.userName()); 00327 uiRequest.insert(SSOUI_KEY_CAPTION, info.caption()); 00328 00329 queryUserPassword(uiRequest); 00330 return false; 00331 } 00332 00333 bool SignonIdentity::verifySecret(const QString &secret) 00334 { 00335 SIGNON_RETURN_IF_CAM_UNAVAILABLE(false); 00336 00337 bool ok; 00338 queryInfo(ok); 00339 if (!ok) { 00340 TRACE(); 00341 sendErrorReply(SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_NAME, 00342 SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_STR + 00343 QLatin1String("Database querying error occurred.")); 00344 return false; 00345 } 00346 00347 CredentialsDB *db = CredentialsAccessManager::instance()->credentialsDB(); 00348 bool ret = db->checkPassword(m_pInfo->id(), m_pInfo->userName(), secret); 00349 00350 keepInUse(); 00351 return ret; 00352 } 00353 00354 void SignonIdentity::remove() 00355 { 00356 SIGNON_RETURN_IF_CAM_UNAVAILABLE(); 00357 00358 CredentialsDB *db = CredentialsAccessManager::instance()->credentialsDB(); 00359 if ((db == 0) || !db->removeCredentials(m_id)) { 00360 TRACE() << "Error occurred while inserting/updating credentials."; 00361 sendErrorReply(SIGNOND_REMOVE_FAILED_ERR_NAME, 00362 SIGNOND_REMOVE_FAILED_ERR_STR + 00363 QLatin1String("Database error occurred.")); 00364 return; 00365 } 00366 emit infoUpdated((int)SignOn::IdentityRemoved); 00367 keepInUse(); 00368 } 00369 00370 bool SignonIdentity::signOut() 00371 { 00372 TRACE() << "Signout request. Identity ID: " << id(); 00373 /* 00374 * - If the identity is stored (thus registered here) 00375 * signal 'sign out' to all identities subsribed to this object, 00376 * otherwise the only identity subscribed to this is the newly 00377 * created client side identity, which called this method. 00378 * - This is just a safety check, as the client identity - if it is a new 00379 * one - should not inform server side to sign out. 00380 */ 00381 if (id() != SIGNOND_NEW_IDENTITY) { 00382 //clear stored sessiondata 00383 CredentialsDB *db = 00384 CredentialsAccessManager::instance()->credentialsDB(); 00385 if ((db == 0) || !db->removeData(m_id)) { 00386 TRACE() << "clear data failed"; 00387 } 00388 00389 emit infoUpdated((int)SignOn::IdentitySignedOut); 00390 } 00391 keepInUse(); 00392 return true; 00393 } 00394 00395 quint32 SignonIdentity::store(const QVariantMap &info) 00396 { 00397 keepInUse(); 00398 SIGNON_RETURN_IF_CAM_UNAVAILABLE(SIGNOND_NEW_IDENTITY); 00399 00400 QString secret = info.value(SIGNOND_IDENTITY_INFO_SECRET).toString(); 00401 QString appId = 00402 AccessControlManagerHelper::instance()->appIdOfPeer( 00403 (static_cast<QDBusContext>(*this)).message()); 00404 00405 bool storeSecret = info.value(SIGNOND_IDENTITY_INFO_STORESECRET).toBool(); 00406 QVariant container = info.value(SIGNOND_IDENTITY_INFO_AUTHMETHODS); 00407 MethodMap methods = 00408 qdbus_cast<MethodMap>(container.value<QDBusArgument>()); 00409 00410 //Add creator to owner list if it has AID 00411 QStringList ownerList = 00412 info.value(SIGNOND_IDENTITY_INFO_OWNER).toStringList(); 00413 if (!appId.isNull()) 00414 ownerList.append(appId); 00415 00416 if (m_pInfo == 0) { 00417 m_pInfo = new SignonIdentityInfo(info); 00418 m_pInfo->setMethods(methods); 00419 m_pInfo->setOwnerList(ownerList); 00420 } else { 00421 QString userName = 00422 info.value(SIGNOND_IDENTITY_INFO_USERNAME).toString(); 00423 QString caption = 00424 info.value(SIGNOND_IDENTITY_INFO_CAPTION).toString(); 00425 QStringList realms = 00426 info.value(SIGNOND_IDENTITY_INFO_REALMS).toStringList(); 00427 QStringList accessControlList = 00428 info.value(SIGNOND_IDENTITY_INFO_ACL).toStringList(); 00429 int type = info.value(SIGNOND_IDENTITY_INFO_TYPE).toInt(); 00430 00431 m_pInfo->setUserName(userName); 00432 m_pInfo->setCaption(caption); 00433 m_pInfo->setMethods(methods); 00434 m_pInfo->setRealms(realms); 00435 m_pInfo->setAccessControlList(accessControlList); 00436 m_pInfo->setOwnerList(ownerList); 00437 m_pInfo->setType(type); 00438 } 00439 00440 if (storeSecret) { 00441 m_pInfo->setPassword(secret); 00442 } else { 00443 m_pInfo->setPassword(QString()); 00444 } 00445 m_id = storeCredentials(*m_pInfo, storeSecret); 00446 00447 if (m_id == SIGNOND_NEW_IDENTITY) { 00448 sendErrorReply(SIGNOND_STORE_FAILED_ERR_NAME, 00449 SIGNOND_STORE_FAILED_ERR_STR); 00450 } 00451 00452 return m_id; 00453 } 00454 00455 quint32 SignonIdentity::storeCredentials(const SignonIdentityInfo &info, 00456 bool storeSecret) 00457 { 00458 CredentialsDB *db = CredentialsAccessManager::instance()->credentialsDB(); 00459 if (db == NULL) { 00460 BLAME() << "NULL database handler object."; 00461 return SIGNOND_NEW_IDENTITY; 00462 } 00463 00464 bool newIdentity = info.isNew(); 00465 00466 if (newIdentity) 00467 m_id = db->insertCredentials(info, storeSecret); 00468 else 00469 db->updateCredentials(info, storeSecret); 00470 00471 if (db->errorOccurred()) { 00472 if (newIdentity) 00473 m_id = SIGNOND_NEW_IDENTITY; 00474 00475 TRACE() << "Error occurred while inserting/updating credentials."; 00476 } else { 00477 if (m_pInfo) { 00478 delete m_pInfo; 00479 m_pInfo = NULL; 00480 } 00481 m_pSignonDaemon->identityStored(this); 00482 00483 //If secrets db is not available cache auth. data. 00484 if (!db->isSecretsDBOpen()) { 00485 AuthCache *cache = new AuthCache; 00486 cache->setUsername(info.userName()); 00487 cache->setPassword(info.password()); 00488 AuthCoreCache::instance()->insert( 00489 AuthCoreCache::CacheId(m_id, AuthCoreCache::AuthMethod()), 00490 cache); 00491 } 00492 TRACE() << "FRESH, JUST STORED CREDENTIALS ID:" << m_id; 00493 emit infoUpdated((int)SignOn::IdentityDataUpdated); 00494 } 00495 return m_id; 00496 } 00497 00498 void SignonIdentity::queryUiSlot(QDBusPendingCallWatcher *call) 00499 { 00500 TRACE(); 00501 setAutoDestruct(true); 00502 00503 QDBusMessage errReply; 00504 QDBusPendingReply<QVariantMap> reply; 00505 if (call != NULL) { 00506 reply = *call; 00507 call->deleteLater(); 00508 } 00509 QVariantMap resultParameters; 00510 if (!reply.isError() && reply.count()) { 00511 resultParameters = reply.argumentAt<0>(); 00512 } else { 00513 errReply = 00514 m_message.createErrorReply( 00515 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME, 00516 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR); 00517 SIGNOND_BUS.send(errReply); 00518 return; 00519 } 00520 00521 if (!resultParameters.contains(SSOUI_KEY_ERROR)) { 00522 //no reply code 00523 errReply = m_message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME, 00524 SIGNOND_INTERNAL_SERVER_ERR_STR); 00525 SIGNOND_BUS.send(errReply); 00526 return; 00527 } 00528 00529 int errorCode = resultParameters.value(SSOUI_KEY_ERROR).toInt(); 00530 TRACE() << "error: " << errorCode; 00531 if (errorCode != QUERY_ERROR_NONE) { 00532 if (errorCode == QUERY_ERROR_CANCELED) 00533 errReply = 00534 m_message.createErrorReply( 00535 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME, 00536 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR); 00537 else 00538 errReply = 00539 m_message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME, 00540 QString(QLatin1String("signon-ui call returned error %1")). 00541 arg(errorCode)); 00542 00543 SIGNOND_BUS.send(errReply); 00544 return; 00545 } 00546 00547 if (resultParameters.contains(SSOUI_KEY_PASSWORD)) { 00548 CredentialsDB *db = 00549 CredentialsAccessManager::instance()->credentialsDB(); 00550 if (db == NULL) { 00551 BLAME() << "NULL database handler object."; 00552 errReply = m_message.createErrorReply(SIGNOND_STORE_FAILED_ERR_NAME, 00553 SIGNOND_STORE_FAILED_ERR_STR); 00554 SIGNOND_BUS.send(errReply); 00555 return; 00556 } 00557 00558 //store new password 00559 if (m_pInfo) { 00560 m_pInfo->setPassword(resultParameters[SSOUI_KEY_PASSWORD].toString()); 00561 00562 quint32 ret = db->updateCredentials(*m_pInfo, true); 00563 delete m_pInfo; 00564 m_pInfo = NULL; 00565 if (ret != SIGNOND_NEW_IDENTITY) { 00566 QDBusMessage dbusreply = m_message.createReply(); 00567 dbusreply << quint32(m_id); 00568 SIGNOND_BUS.send(dbusreply); 00569 return; 00570 } else{ 00571 BLAME() << "Error during update"; 00572 } 00573 } 00574 } 00575 00576 //this should not happen, return error 00577 errReply = m_message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME, 00578 SIGNOND_INTERNAL_SERVER_ERR_STR); 00579 SIGNOND_BUS.send(errReply); 00580 return; 00581 } 00582 00583 void SignonIdentity::verifyUiSlot(QDBusPendingCallWatcher *call) 00584 { 00585 TRACE(); 00586 setAutoDestruct(true); 00587 00588 QDBusMessage errReply; 00589 QDBusPendingReply<QVariantMap> reply; 00590 if (call != NULL) { 00591 reply = *call; 00592 call->deleteLater(); 00593 } 00594 QVariantMap resultParameters; 00595 if (!reply.isError() && reply.count()) { 00596 resultParameters = reply.argumentAt<0>(); 00597 } else { 00598 errReply = 00599 m_message.createErrorReply( 00600 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME, 00601 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR); 00602 SIGNOND_BUS.send(errReply); 00603 return; 00604 } 00605 00606 if (!resultParameters.contains(SSOUI_KEY_ERROR)) { 00607 //no reply code 00608 errReply = m_message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME, 00609 SIGNOND_INTERNAL_SERVER_ERR_STR); 00610 SIGNOND_BUS.send(errReply); 00611 return; 00612 } 00613 00614 int errorCode = resultParameters.value(SSOUI_KEY_ERROR).toInt(); 00615 TRACE() << "error: " << errorCode; 00616 if (errorCode != QUERY_ERROR_NONE) { 00617 if (errorCode == QUERY_ERROR_CANCELED) 00618 errReply = m_message.createErrorReply( 00619 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME, 00620 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR); 00621 else if (errorCode == QUERY_ERROR_FORGOT_PASSWORD) 00622 errReply = m_message.createErrorReply( 00623 SIGNOND_FORGOT_PASSWORD_ERR_NAME, 00624 SIGNOND_FORGOT_PASSWORD_ERR_STR); 00625 else 00626 errReply = m_message.createErrorReply( 00627 SIGNOND_INTERNAL_SERVER_ERR_NAME, 00628 QString(QLatin1String("signon-ui call " 00629 "returned error %1")). 00630 arg(errorCode)); 00631 00632 SIGNOND_BUS.send(errReply); 00633 return; 00634 } 00635 00636 if (resultParameters.contains(SSOUI_KEY_PASSWORD)) { 00637 CredentialsDB *db = 00638 CredentialsAccessManager::instance()->credentialsDB(); 00639 if (db == NULL) { 00640 BLAME() << "NULL database handler object."; 00641 errReply = m_message.createErrorReply(SIGNOND_STORE_FAILED_ERR_NAME, 00642 SIGNOND_STORE_FAILED_ERR_STR); 00643 SIGNOND_BUS.send(errReply); 00644 return; 00645 } 00646 00647 //compare passwords 00648 if (m_pInfo) { 00649 bool ret = 00650 m_pInfo->password() == resultParameters[SSOUI_KEY_PASSWORD]. 00651 toString(); 00652 00653 if (!ret && resultParameters.contains(SSOUI_KEY_CONFIRMCOUNT)) { 00654 int count = resultParameters[SSOUI_KEY_CONFIRMCOUNT].toInt(); 00655 TRACE() << "retry count:" << count; 00656 if (count > 0) { //retry 00657 resultParameters[SSOUI_KEY_CONFIRMCOUNT] = (count-1); 00658 resultParameters[SSOUI_KEY_MESSAGEID] = 00659 QUERY_MESSAGE_NOT_AUTHORIZED; 00660 queryUserPassword(resultParameters); 00661 return; 00662 } else { 00663 //TODO show error note here if needed 00664 } 00665 } 00666 delete m_pInfo; 00667 m_pInfo = NULL; 00668 QDBusMessage dbusreply = m_message.createReply(); 00669 dbusreply << ret; 00670 SIGNOND_BUS.send(dbusreply); 00671 return; 00672 } 00673 } 00674 //this should not happen, return error 00675 errReply = m_message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME, 00676 SIGNOND_INTERNAL_SERVER_ERR_STR); 00677 SIGNOND_BUS.send(errReply); 00678 return; 00679 } 00680 00681 } //namespace SignonDaemonNS