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(),
108 SignonIdentity::~SignonIdentity()
133 bool needLoadFromDB =
true;
135 needLoadFromDB =
false;
136 if (queryPassword && m_pInfo->
password().isEmpty()) {
137 needLoadFromDB =
true;
141 if (needLoadFromDB) {
160 if (!queryPassword) {
168 TRACE() <<
"addReference: " << reference;
174 BLAME() <<
"NULL database handler object.";
177 const QDBusContext &context =
static_cast<QDBusContext
>(*this);
180 context.connection(),
188 TRACE() <<
"removeReference: " << reference;
194 BLAME() <<
"NULL database handler object.";
197 const QDBusContext &context =
static_cast<QDBusContext
>(*this);
200 context.connection(),
214 BLAME() <<
"Identity not found.";
215 sendErrorReply(SIGNOND_IDENTITY_NOT_FOUND_ERR_NAME,
216 SIGNOND_IDENTITY_NOT_FOUND_ERR_STR);
217 return SIGNOND_NEW_IDENTITY;
220 BLAME() <<
"Password cannot be stored.";
221 sendErrorReply(SIGNOND_STORE_FAILED_ERR_NAME,
222 SIGNOND_STORE_FAILED_ERR_STR);
223 return SIGNOND_NEW_IDENTITY;
227 setDelayedReply(
true);
230 QVariantMap uiRequest;
231 uiRequest.insert(SSOUI_KEY_QUERYPASSWORD,
true);
232 uiRequest.insert(SSOUI_KEY_USERNAME, info.
userName());
233 uiRequest.insert(SSOUI_KEY_MESSAGE, displayMessage);
234 uiRequest.insert(SSOUI_KEY_CAPTION, info.
caption());
236 TRACE() <<
"Waiting for reply from signon-ui";
240 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
241 this, SLOT(
queryUiSlot(QDBusPendingCallWatcher*)));
249 TRACE() <<
"QUERYING INFO";
258 sendErrorReply(SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_NAME,
259 SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_STR +
260 QLatin1String(
"Database querying error occurred."));
261 return QVariantMap();
266 sendErrorReply(SIGNOND_IDENTITY_NOT_FOUND_ERR_NAME,
267 SIGNOND_IDENTITY_NOT_FOUND_ERR_STR);
268 return QVariantMap();
276 void SignonIdentity::queryUserPassword(
const QVariantMap ¶ms,
277 const QDBusConnection &connection,
278 const QDBusMessage &message)
280 TRACE() <<
"Waiting for reply from signon-ui";
283 connection, message,
this);
284 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
this,
298 BLAME() <<
"Identity not found.";
299 sendErrorReply(SIGNOND_IDENTITY_NOT_FOUND_ERR_NAME,
300 SIGNOND_IDENTITY_NOT_FOUND_ERR_STR);
304 BLAME() <<
"Password is not stored.";
305 sendErrorReply(SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_NAME,
306 SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_STR);
311 setDelayedReply(
true);
314 QVariantMap uiRequest;
315 uiRequest.unite(params);
316 uiRequest.insert(SSOUI_KEY_QUERYPASSWORD,
true);
317 uiRequest.insert(SSOUI_KEY_USERNAME, info.
userName());
318 uiRequest.insert(SSOUI_KEY_CAPTION, info.
caption());
320 queryUserPassword(uiRequest, connection(), message());
332 sendErrorReply(SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_NAME,
333 SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_STR +
334 QLatin1String(
"Database querying error occurred."));
351 TRACE() <<
"Error occurred while inserting/updating credentials.";
352 sendErrorReply(SIGNOND_REMOVE_FAILED_ERR_NAME,
353 SIGNOND_REMOVE_FAILED_ERR_STR +
354 QLatin1String(
"Database error occurred."));
357 setDelayedReply(
true);
362 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
363 this, SLOT(removeCompleted(QDBusPendingCallWatcher*)));
367 void SignonIdentity::removeCompleted(QDBusPendingCallWatcher *call)
369 Q_ASSERT(call != NULL);
376 QDBusPendingReply<> signOnUiReply = *call;
377 bool ok = !signOnUiReply.isError();
378 TRACE() << (ok ?
"removeIdentityData succeeded" :
"removeIdentityData failed");
382 QDBusMessage reply = context->message().createReply();
383 context->connection().send(reply);
388 TRACE() <<
"Signout request. Identity ID: " <<
id();
397 if (
id() != SIGNOND_NEW_IDENTITY) {
402 TRACE() <<
"clear data failed";
405 setDelayedReply(
true);
410 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
411 this, SLOT(signOutCompleted(QDBusPendingCallWatcher*)));
417 void SignonIdentity::signOutCompleted(QDBusPendingCallWatcher *call)
419 Q_ASSERT(call != NULL);
426 QDBusPendingReply<> signOnUiReply = *call;
427 bool ok = !signOnUiReply.isError();
428 TRACE() << (ok ?
"removeIdentityData succeeded" :
"removeIdentityData failed");
432 QDBusMessage reply = context->message().createReply();
434 context->connection().send(reply);
442 const QDBusContext &context =
static_cast<QDBusContext
>(*this);
445 context.connection(),
448 const QVariant container = info.value(SIGNOND_IDENTITY_INFO_AUTHMETHODS);
449 MethodMap methods = container.isValid() ?
453 QStringList ownerList =
454 info.value(SIGNOND_IDENTITY_INFO_OWNER).toStringList();
456 ownerList.append(appId);
463 if (info.contains(SIGNOND_IDENTITY_INFO_SECRET)) {
464 QString secret = info.value(SIGNOND_IDENTITY_INFO_SECRET).toString();
468 info.value(SIGNOND_IDENTITY_INFO_STORESECRET).toBool();
470 info.value(SIGNOND_IDENTITY_INFO_USERNAME).toString();
472 info.value(SIGNOND_IDENTITY_INFO_CAPTION).toString();
474 info.value(SIGNOND_IDENTITY_INFO_REALMS).toStringList();
475 QStringList accessControlList =
476 info.value(SIGNOND_IDENTITY_INFO_ACL).toStringList();
477 int type = info.value(SIGNOND_IDENTITY_INFO_TYPE).toInt();
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);
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);
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
void setRealms(const QStringList &realms)
#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 setStorePassword(bool storePassword)
void setMethods(const MethodMap &methods)
void destroy()
Performs any predestruction operations and the destruction itself.
void verifyUiSlot(QDBusPendingCallWatcher *call)
friend class PendingCallWatcherWithContext
quint32 insertCredentials(const SignonIdentityInfo &info)
quint32 updateCredentials(const SignonIdentityInfo &info)
SignOn::CredentialsDBError lastError() const
bool verifySecret(const QString &secret)
void setCaption(const QString &caption)
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)
QDBusPendingCall queryDialog(const QVariantMap ¶meters)
bool removeReference(const quint32 id, const QString &token, const QString &reference=QString())
const QString internalServerErrStr
QDBusPendingCall removeIdentityData(quint32 id)
QMap< MethodName, MechanismsList > MethodMap
quint32 store(const QVariantMap &info)
void setAccessControlList(const QStringList &accessControlList)
bool errorOccurred() const
bool removeReference(const QString &reference)
Daemon side representation of identity.
void stored(SignonIdentity *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)
void setUserName(const QString &userName)
void setAutoDestruct(bool value=true) const
Mark the object as used.
SignonIdentityInfo queryInfo(bool &ok, bool queryPassword=true)
const QVariantMap toMap() const
void keepInUse() const
Mark the object as used.
int identityTimeout() const
Returns the number of seconds of inactivity after which identity objects might be automatically delet...
void setOwnerList(const QStringList &owners)