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";
246 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
247 this, SLOT(
queryUiSlot(QDBusPendingCallWatcher*)));
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";
289 connection, message,
this);
290 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
this,
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."));
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);
368 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
369 this, SLOT(removeCompleted(QDBusPendingCallWatcher*)));
373 void SignonIdentity::removeCompleted(QDBusPendingCallWatcher *call)
375 Q_ASSERT(call != NULL);
382 QDBusPendingReply<> signOnUiReply = *call;
383 bool ok = !signOnUiReply.isError();
384 TRACE() << (ok ?
"removeIdentityData succeeded" :
"removeIdentityData failed");
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);
416 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
417 this, SLOT(signOutCompleted(QDBusPendingCallWatcher*)));
423 void SignonIdentity::signOutCompleted(QDBusPendingCallWatcher *call)
425 Q_ASSERT(call != NULL);
432 QDBusPendingReply<> signOnUiReply = *call;
433 bool ok = !signOnUiReply.isError();
434 TRACE() << (ok ?
"removeIdentityData succeeded" :
"removeIdentityData failed");
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() ?
475 QStringList ownerList =
476 info.value(SIGNOND_IDENTITY_INFO_OWNER).toStringList();
478 ownerList.append(appId);
485 if (info.contains(SIGNOND_IDENTITY_INFO_SECRET)) {
486 QString secret = info.value(SIGNOND_IDENTITY_INFO_SECRET).toString();
490 info.value(SIGNOND_IDENTITY_INFO_STORESECRET).toBool();
492 info.value(SIGNOND_IDENTITY_INFO_USERNAME).toString();
494 info.value(SIGNOND_IDENTITY_INFO_CAPTION).toString();
496 info.value(SIGNOND_IDENTITY_INFO_REALMS).toStringList();
497 QStringList accessControlList =
498 info.value(SIGNOND_IDENTITY_INFO_ACL).toStringList();
499 int type = info.value(SIGNOND_IDENTITY_INFO_TYPE).toInt();
513 if (m_id == SIGNOND_NEW_IDENTITY) {
514 sendErrorReply(SIGNOND_STORE_FAILED_ERR_NAME,
515 SIGNOND_STORE_FAILED_ERR_STR);
525 BLAME() <<
"NULL database handler object.";
526 return SIGNOND_NEW_IDENTITY;
529 bool newIdentity = info.
isNew();
538 m_id = SIGNOND_NEW_IDENTITY;
540 TRACE() <<
"Error occurred while inserting/updating credentials.";
548 TRACE() <<
"FRESH, JUST STORED CREDENTIALS ID:" << m_id;
549 emit
infoUpdated((
int)SignOn::IdentityDataUpdated);
557 Q_ASSERT(call != NULL);
563 const QDBusMessage &message = context->message();
564 const QDBusConnection &connection = context->connection();
566 QDBusMessage errReply;
567 QDBusPendingReply<QVariantMap> reply = *call;
570 QVariantMap resultParameters;
571 if (!reply.isError() && reply.count()) {
572 resultParameters = reply.argumentAt<0>();
574 errReply = message.createErrorReply(
575 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME,
576 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR);
577 connection.send(errReply);
581 if (!resultParameters.contains(SSOUI_KEY_ERROR)) {
583 errReply = message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
584 SIGNOND_INTERNAL_SERVER_ERR_STR);
585 connection.send(errReply);
589 int errorCode = resultParameters.value(SSOUI_KEY_ERROR).toInt();
590 TRACE() <<
"error: " << errorCode;
591 if (errorCode != QUERY_ERROR_NONE) {
592 if (errorCode == QUERY_ERROR_CANCELED)
594 message.createErrorReply(
595 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME,
596 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR);
599 message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
600 QString(QLatin1String(
"signon-ui call returned error %1")).
603 connection.send(errReply);
607 if (resultParameters.contains(SSOUI_KEY_PASSWORD)) {
611 BLAME() <<
"NULL database handler object.";
612 errReply = message.createErrorReply(SIGNOND_STORE_FAILED_ERR_NAME,
613 SIGNOND_STORE_FAILED_ERR_STR);
614 connection.send(errReply);
620 m_pInfo->
setPassword(resultParameters[SSOUI_KEY_PASSWORD].toString());
625 if (ret != SIGNOND_NEW_IDENTITY) {
626 QDBusMessage dbusreply = message.createReply();
627 dbusreply << quint32(m_id);
628 connection.send(dbusreply);
631 BLAME() <<
"Error during update";
637 errReply = message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
638 SIGNOND_INTERNAL_SERVER_ERR_STR);
639 connection.send(errReply);
646 Q_ASSERT(call != NULL);
652 const QDBusMessage &message = context->message();
653 const QDBusConnection &connection = context->connection();
655 QDBusMessage errReply;
656 QDBusPendingReply<QVariantMap> reply = *call;
658 QVariantMap resultParameters;
659 if (!reply.isError() && reply.count()) {
660 resultParameters = reply.argumentAt<0>();
663 message.createErrorReply(
664 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME,
665 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR);
666 connection.send(errReply);
670 if (!resultParameters.contains(SSOUI_KEY_ERROR)) {
672 errReply = message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
673 SIGNOND_INTERNAL_SERVER_ERR_STR);
674 connection.send(errReply);
678 int errorCode = resultParameters.value(SSOUI_KEY_ERROR).toInt();
679 TRACE() <<
"error: " << errorCode;
680 if (errorCode != QUERY_ERROR_NONE) {
681 if (errorCode == QUERY_ERROR_CANCELED)
682 errReply = message.createErrorReply(
683 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME,
684 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR);
685 else if (errorCode == QUERY_ERROR_FORGOT_PASSWORD)
686 errReply = message.createErrorReply(
687 SIGNOND_FORGOT_PASSWORD_ERR_NAME,
688 SIGNOND_FORGOT_PASSWORD_ERR_STR);
690 errReply = message.createErrorReply(
691 SIGNOND_INTERNAL_SERVER_ERR_NAME,
692 QString(QLatin1String(
"signon-ui call "
693 "returned error %1")).
696 connection.send(errReply);
700 if (resultParameters.contains(SSOUI_KEY_PASSWORD)) {
704 BLAME() <<
"NULL database handler object.";
705 errReply = message.createErrorReply(SIGNOND_STORE_FAILED_ERR_NAME,
706 SIGNOND_STORE_FAILED_ERR_STR);
707 connection.send(errReply);
714 m_pInfo->
password() == resultParameters[SSOUI_KEY_PASSWORD].
717 if (!ret && resultParameters.contains(SSOUI_KEY_CONFIRMCOUNT)) {
718 int count = resultParameters[SSOUI_KEY_CONFIRMCOUNT].toInt();
719 TRACE() <<
"retry count:" << count;
721 resultParameters[SSOUI_KEY_CONFIRMCOUNT] = (count-1);
722 resultParameters[SSOUI_KEY_MESSAGEID] =
723 QUERY_MESSAGE_NOT_AUTHORIZED;
724 queryUserPassword(resultParameters, connection, message);
732 QDBusMessage dbusreply = message.createReply();
734 connection.send(dbusreply);
739 errReply = message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
740 SIGNOND_INTERNAL_SERVER_ERR_STR);
741 connection.send(errReply);
747 #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)