28 #include <QVariantMap> 33 #include "SignOn/uisessiondata.h" 34 #include "SignOn/uisessiondata_priv.h" 35 #include "signoncommon.h" 40 #define SIGNON_RETURN_IF_CAM_UNAVAILABLE(_ret_arg_) do { \ 41 if (!(CredentialsAccessManager::instance()->credentialsSystemOpened())) { \ 42 sendErrorReply(internalServerErrName, \ 43 internalServerErrStr + \ 44 QLatin1String("Could not access Signon Database."));\ 54 class PendingCallWatcherWithContext:
public QDBusPendingCallWatcher
59 PendingCallWatcherWithContext(
const QDBusPendingCall &call,
60 SignonIdentity *parent):
61 QDBusPendingCallWatcher(call, parent),
62 m_connection(parent->connection()),
63 m_message(parent->message())
67 PendingCallWatcherWithContext(
const QDBusPendingCall &call,
68 const QDBusConnection &connection,
69 const QDBusMessage &message,
70 SignonIdentity *parent):
71 QDBusPendingCallWatcher(call, parent),
72 m_connection(connection),
77 const QDBusConnection &connection()
const {
return m_connection; }
78 const QDBusMessage &message()
const {
return m_message; }
81 QDBusConnection m_connection;
82 QDBusMessage m_message;
85 SignonIdentity::SignonIdentity(quint32
id,
int timeout,
86 SignonDaemon *parent):
87 SignonDisposable(timeout, parent),
92 (void)
new SignonIdentityAdaptor(
this);
97 static quint32 incr = 0;
98 QString objectName = SIGNOND_DAEMON_OBJECTPATH + QLatin1String(
"/Identity_")
99 + QString::number(incr++, 16);
100 setObjectName(objectName);
104 QDBusConnection::sessionBus(),
110 QObject::connect(db, SIGNAL(credentialsUpdated(quint32)),
111 this, SLOT(onCredentialsUpdated(quint32)));
114 SignonIdentity::~SignonIdentity()
139 bool needLoadFromDB =
true;
141 needLoadFromDB =
false;
142 if (queryPassword && m_pInfo->password().isEmpty()) {
143 needLoadFromDB =
true;
147 if (needLoadFromDB) {
166 if (!queryPassword) {
174 TRACE() <<
"addReference: " << reference;
180 BLAME() <<
"NULL database handler object.";
183 const QDBusContext &context =
static_cast<QDBusContext
>(*this);
186 context.connection(),
194 TRACE() <<
"removeReference: " << reference;
200 BLAME() <<
"NULL database handler object.";
203 const QDBusContext &context =
static_cast<QDBusContext
>(*this);
206 context.connection(),
220 BLAME() <<
"Identity not found.";
221 sendErrorReply(SIGNOND_IDENTITY_NOT_FOUND_ERR_NAME,
222 SIGNOND_IDENTITY_NOT_FOUND_ERR_STR);
223 return SIGNOND_NEW_IDENTITY;
226 BLAME() <<
"Password cannot be stored.";
227 sendErrorReply(SIGNOND_STORE_FAILED_ERR_NAME,
228 SIGNOND_STORE_FAILED_ERR_STR);
229 return SIGNOND_NEW_IDENTITY;
233 setDelayedReply(
true);
236 QVariantMap uiRequest;
237 uiRequest.insert(SSOUI_KEY_QUERYPASSWORD,
true);
238 uiRequest.insert(SSOUI_KEY_USERNAME, info.
userName());
239 uiRequest.insert(SSOUI_KEY_MESSAGE, displayMessage);
240 uiRequest.insert(SSOUI_KEY_CAPTION, info.
caption());
242 TRACE() <<
"Waiting for reply from signon-ui";
243 PendingCallWatcherWithContext *watcher =
244 new PendingCallWatcherWithContext(m_signonui->queryDialog(uiRequest),
246 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
247 this, SLOT(queryUiSlot(QDBusPendingCallWatcher*)));
249 setAutoDestruct(
false);
255 TRACE() <<
"QUERYING INFO";
264 sendErrorReply(SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_NAME,
265 SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_STR +
266 QLatin1String(
"Database querying error occurred."));
267 return QVariantMap();
272 sendErrorReply(SIGNOND_IDENTITY_NOT_FOUND_ERR_NAME,
273 SIGNOND_IDENTITY_NOT_FOUND_ERR_STR);
274 return QVariantMap();
282 void SignonIdentity::queryUserPassword(
const QVariantMap ¶ms,
283 const QDBusConnection &connection,
284 const QDBusMessage &message)
286 TRACE() <<
"Waiting for reply from signon-ui";
287 PendingCallWatcherWithContext *watcher =
288 new PendingCallWatcherWithContext(m_signonui->queryDialog(params),
289 connection, message,
this);
290 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
this,
291 SLOT(verifyUiSlot(QDBusPendingCallWatcher*)));
293 setAutoDestruct(
false);
304 BLAME() <<
"Identity not found.";
305 sendErrorReply(SIGNOND_IDENTITY_NOT_FOUND_ERR_NAME,
306 SIGNOND_IDENTITY_NOT_FOUND_ERR_STR);
310 BLAME() <<
"Password is not stored.";
311 sendErrorReply(SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_NAME,
312 SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_STR);
317 setDelayedReply(
true);
320 QVariantMap uiRequest;
321 uiRequest.unite(params);
322 uiRequest.insert(SSOUI_KEY_QUERYPASSWORD,
true);
323 uiRequest.insert(SSOUI_KEY_USERNAME, info.
userName());
324 uiRequest.insert(SSOUI_KEY_CAPTION, info.
caption());
326 queryUserPassword(uiRequest, connection(), message());
338 sendErrorReply(SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_NAME,
339 SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_STR +
340 QLatin1String(
"Database querying error occurred."));
345 bool ret = db->
checkPassword(m_pInfo->id(), m_pInfo->userName(), secret);
357 TRACE() <<
"Error occurred while inserting/updating credentials.";
358 sendErrorReply(SIGNOND_REMOVE_FAILED_ERR_NAME,
359 SIGNOND_REMOVE_FAILED_ERR_STR +
360 QLatin1String(
"Database error occurred."));
363 setDelayedReply(
true);
364 setAutoDestruct(
false);
365 PendingCallWatcherWithContext *watcher =
366 new PendingCallWatcherWithContext(m_signonui->removeIdentityData(m_id),
368 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
369 this, SLOT(removeCompleted(QDBusPendingCallWatcher*)));
373 void SignonIdentity::removeCompleted(QDBusPendingCallWatcher *call)
375 Q_ASSERT(call != NULL);
377 setAutoDestruct(
true);
380 PendingCallWatcherWithContext *context =
381 qobject_cast<PendingCallWatcherWithContext*>(call);
382 QDBusPendingReply<> signOnUiReply = *call;
383 bool ok = !signOnUiReply.isError();
384 TRACE() << (ok ?
"removeIdentityData succeeded" :
"removeIdentityData failed");
386 emit infoUpdated((
int)SignOn::IdentityRemoved);
388 QDBusMessage reply = context->message().createReply();
389 context->connection().send(reply);
394 TRACE() <<
"Signout request. Identity ID: " << id();
403 if (
id() != SIGNOND_NEW_IDENTITY) {
408 TRACE() <<
"clear data failed";
411 setDelayedReply(
true);
412 setAutoDestruct(
false);
413 PendingCallWatcherWithContext *watcher =
414 new PendingCallWatcherWithContext(m_signonui->removeIdentityData(m_id),
416 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
417 this, SLOT(signOutCompleted(QDBusPendingCallWatcher*)));
423 void SignonIdentity::signOutCompleted(QDBusPendingCallWatcher *call)
425 Q_ASSERT(call != NULL);
427 setAutoDestruct(
true);
430 PendingCallWatcherWithContext *context =
431 qobject_cast<PendingCallWatcherWithContext*>(call);
432 QDBusPendingReply<> signOnUiReply = *call;
433 bool ok = !signOnUiReply.isError();
434 TRACE() << (ok ?
"removeIdentityData succeeded" :
"removeIdentityData failed");
436 emit infoUpdated((
int)SignOn::IdentitySignedOut);
438 QDBusMessage reply = context->message().createReply();
440 context->connection().send(reply);
443 void SignonIdentity::onCredentialsUpdated(quint32
id)
445 if (
id != m_id)
return;
456 emit infoUpdated((
int)SignOn::IdentityDataUpdated);
464 const QDBusContext &context =
static_cast<QDBusContext
>(*this);
467 context.connection(),
470 const QVariant container = info.value(SIGNOND_IDENTITY_INFO_AUTHMETHODS);
471 MethodMap methods = container.isValid() ?
476 m_pInfo->setMethods(methods);
478 QStringList ownerList =
479 info.value(SIGNOND_IDENTITY_INFO_OWNER).toStringList();
480 if (!appId.isNull()) {
481 ownerList.append(appId);
483 m_pInfo->setOwnerList(ownerList);
486 m_pInfo->update(newInfo);
489 m_id = storeCredentials(*m_pInfo);
491 if (m_id == SIGNOND_NEW_IDENTITY) {
492 sendErrorReply(SIGNOND_STORE_FAILED_ERR_NAME,
493 SIGNOND_STORE_FAILED_ERR_STR);
503 BLAME() <<
"NULL database handler object.";
504 return SIGNOND_NEW_IDENTITY;
507 bool newIdentity = info.
isNew();
516 m_id = SIGNOND_NEW_IDENTITY;
518 TRACE() <<
"Error occurred while inserting/updating credentials.";
526 TRACE() <<
"FRESH, JUST STORED CREDENTIALS ID:" << m_id;
527 emit infoUpdated((
int)SignOn::IdentityDataUpdated);
535 Q_ASSERT(call != NULL);
537 setAutoDestruct(
true);
539 PendingCallWatcherWithContext *context =
540 qobject_cast<PendingCallWatcherWithContext*>(call);
541 const QDBusMessage &message = context->message();
542 const QDBusConnection &connection = context->connection();
544 QDBusMessage errReply;
545 QDBusPendingReply<QVariantMap> reply = *call;
548 QVariantMap resultParameters;
549 if (!reply.isError() && reply.count()) {
550 resultParameters = reply.argumentAt<0>();
552 errReply = message.createErrorReply(
553 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME,
554 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR);
555 connection.send(errReply);
559 if (!resultParameters.contains(SSOUI_KEY_ERROR)) {
561 errReply = message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
562 SIGNOND_INTERNAL_SERVER_ERR_STR);
563 connection.send(errReply);
567 int errorCode = resultParameters.value(SSOUI_KEY_ERROR).toInt();
568 TRACE() <<
"error: " << errorCode;
569 if (errorCode != QUERY_ERROR_NONE) {
570 if (errorCode == QUERY_ERROR_CANCELED)
572 message.createErrorReply(
573 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME,
574 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR);
577 message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
578 QString(QLatin1String(
"signon-ui call returned error %1")).
581 connection.send(errReply);
585 if (resultParameters.contains(SSOUI_KEY_PASSWORD)) {
589 BLAME() <<
"NULL database handler object.";
590 errReply = message.createErrorReply(SIGNOND_STORE_FAILED_ERR_NAME,
591 SIGNOND_STORE_FAILED_ERR_STR);
592 connection.send(errReply);
598 m_pInfo->setPassword(resultParameters[SSOUI_KEY_PASSWORD].toString());
603 if (ret != SIGNOND_NEW_IDENTITY) {
604 QDBusMessage dbusreply = message.createReply();
605 dbusreply << quint32(m_id);
606 connection.send(dbusreply);
609 BLAME() <<
"Error during update";
615 errReply = message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
616 SIGNOND_INTERNAL_SERVER_ERR_STR);
617 connection.send(errReply);
624 Q_ASSERT(call != NULL);
626 setAutoDestruct(
true);
628 PendingCallWatcherWithContext *context =
629 qobject_cast<PendingCallWatcherWithContext*>(call);
630 const QDBusMessage &message = context->message();
631 const QDBusConnection &connection = context->connection();
633 QDBusMessage errReply;
634 QDBusPendingReply<QVariantMap> reply = *call;
636 QVariantMap resultParameters;
637 if (!reply.isError() && reply.count()) {
638 resultParameters = reply.argumentAt<0>();
641 message.createErrorReply(
642 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME,
643 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR);
644 connection.send(errReply);
648 if (!resultParameters.contains(SSOUI_KEY_ERROR)) {
650 errReply = message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
651 SIGNOND_INTERNAL_SERVER_ERR_STR);
652 connection.send(errReply);
656 int errorCode = resultParameters.value(SSOUI_KEY_ERROR).toInt();
657 TRACE() <<
"error: " << errorCode;
658 if (errorCode != QUERY_ERROR_NONE) {
659 if (errorCode == QUERY_ERROR_CANCELED)
660 errReply = message.createErrorReply(
661 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME,
662 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR);
663 else if (errorCode == QUERY_ERROR_FORGOT_PASSWORD)
664 errReply = message.createErrorReply(
665 SIGNOND_FORGOT_PASSWORD_ERR_NAME,
666 SIGNOND_FORGOT_PASSWORD_ERR_STR);
668 errReply = message.createErrorReply(
669 SIGNOND_INTERNAL_SERVER_ERR_NAME,
670 QString(QLatin1String(
"signon-ui call " 671 "returned error %1")).
674 connection.send(errReply);
678 if (resultParameters.contains(SSOUI_KEY_PASSWORD)) {
682 BLAME() <<
"NULL database handler object.";
683 errReply = message.createErrorReply(SIGNOND_STORE_FAILED_ERR_NAME,
684 SIGNOND_STORE_FAILED_ERR_STR);
685 connection.send(errReply);
692 m_pInfo->password() == resultParameters[SSOUI_KEY_PASSWORD].
695 if (!ret && resultParameters.contains(SSOUI_KEY_CONFIRMCOUNT)) {
696 int count = resultParameters[SSOUI_KEY_CONFIRMCOUNT].toInt();
697 TRACE() <<
"retry count:" << count;
699 resultParameters[SSOUI_KEY_CONFIRMCOUNT] = (count-1);
700 resultParameters[SSOUI_KEY_MESSAGEID] =
701 QUERY_MESSAGE_NOT_AUTHORIZED;
702 queryUserPassword(resultParameters, connection, message);
710 QDBusMessage dbusreply = message.createReply();
712 connection.send(dbusreply);
717 errReply = message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
718 SIGNOND_INTERNAL_SERVER_ERR_STR);
719 connection.send(errReply);
725 #include "signonidentity.moc" bool removeData(const quint32 id, const QString &method=QString())
const QString internalServerErrName
#define SIGNON_RETURN_IF_CAM_UNAVAILABLE(_ret_arg_)
QString appIdOfPeer(const QDBusConnection &peerConnection, const QDBusMessage &peerMessage)
Looks up for the application identifier of a specific client process.
quint32 requestCredentialsUpdate(const QString &message)
bool storePassword() const
static AccessControlManagerHelper * instance()
bool addReference(const QString &reference)
void destroy()
Performs any predestruction operations and the destruction itself.
void verifyUiSlot(QDBusPendingCallWatcher *call)
quint32 insertCredentials(const SignonIdentityInfo &info)
quint32 updateCredentials(const SignonIdentityInfo &info)
SignOn::CredentialsDBError lastError() const
bool verifySecret(const QString &secret)
bool addReference(const quint32 id, const QString &token, const QString &reference)
bool verifyUser(const QVariantMap ¶ms)
bool removeCredentials(const quint32 id)
static SignonIdentity * createIdentity(quint32 id, SignonDaemon *parent)
static CredentialsAccessManager * instance()
Returns CAM instance.
#define SIGNON_UI_SERVICE
void setPassword(const QString &password)
void queryUiSlot(QDBusPendingCallWatcher *call)
SignonIdentityInfo credentials(const quint32 id, bool queryPassword=true)
bool removeReference(const quint32 id, const QString &token, const QString &reference=QString())
const QString internalServerErrStr
QMap< MethodName, MechanismsList > MethodMap
quint32 store(const QVariantMap &info)
bool errorOccurred() const
bool removeReference(const QString &reference)
Daemon side representation of identity.
Daemon side representation of identity information.
bool checkPassword(const quint32 id, const QString &username, const QString &password)
CredentialsDB * credentialsDB() const
Manages the credentials I/O.
Helper class for access control-related functionality.
#define SIGNON_UI_DAEMON_OBJECTPATH
quint32 storeCredentials(const SignonIdentityInfo &info)
SignonIdentityInfo queryInfo(bool &ok, bool queryPassword=true)
const QVariantMap toMap() const
int identityTimeout() const
Returns the number of seconds of inactivity after which identity objects might be automatically delet...