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."));\
49 namespace SignonDaemonNS {
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() ?
478 QStringList ownerList =
479 info.value(SIGNOND_IDENTITY_INFO_OWNER).toStringList();
480 if (!appId.isNull()) {
481 ownerList.append(appId);
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
#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 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)
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)
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 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 update(const SignonIdentityInfo &info)
void setOwnerList(const QStringList &owners)