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(),
108 SignonIdentity::~SignonIdentity()
130 bool needLoadFromDB =
true;
132 needLoadFromDB =
false;
133 if (queryPassword && m_pInfo->
password().isEmpty()) {
134 needLoadFromDB =
true;
138 if (needLoadFromDB) {
157 if (!queryPassword) {
165 TRACE() <<
"addReference: " << reference;
171 BLAME() <<
"NULL database handler object.";
174 const QDBusContext &context =
static_cast<QDBusContext
>(*this);
177 context.connection(),
185 TRACE() <<
"removeReference: " << reference;
191 BLAME() <<
"NULL database handler object.";
194 const QDBusContext &context =
static_cast<QDBusContext
>(*this);
197 context.connection(),
211 BLAME() <<
"Identity not found.";
212 sendErrorReply(SIGNOND_IDENTITY_NOT_FOUND_ERR_NAME,
213 SIGNOND_IDENTITY_NOT_FOUND_ERR_STR);
214 return SIGNOND_NEW_IDENTITY;
217 BLAME() <<
"Password cannot be stored.";
218 sendErrorReply(SIGNOND_STORE_FAILED_ERR_NAME,
219 SIGNOND_STORE_FAILED_ERR_STR);
220 return SIGNOND_NEW_IDENTITY;
224 setDelayedReply(
true);
227 QVariantMap uiRequest;
228 uiRequest.insert(SSOUI_KEY_QUERYPASSWORD,
true);
229 uiRequest.insert(SSOUI_KEY_USERNAME, info.
userName());
230 uiRequest.insert(SSOUI_KEY_MESSAGE, displayMessage);
231 uiRequest.insert(SSOUI_KEY_CAPTION, info.
caption());
233 TRACE() <<
"Waiting for reply from signon-ui";
237 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
238 this, SLOT(
queryUiSlot(QDBusPendingCallWatcher*)));
246 TRACE() <<
"QUERYING INFO";
255 sendErrorReply(SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_NAME,
256 SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_STR +
257 QLatin1String(
"Database querying error occurred."));
258 return QVariantMap();
263 sendErrorReply(SIGNOND_IDENTITY_NOT_FOUND_ERR_NAME,
264 SIGNOND_IDENTITY_NOT_FOUND_ERR_STR);
265 return QVariantMap();
272 void SignonIdentity::queryUserPassword(
const QVariantMap ¶ms,
273 const QDBusConnection &connection,
274 const QDBusMessage &message)
276 TRACE() <<
"Waiting for reply from signon-ui";
279 connection, message,
this);
280 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
this,
294 BLAME() <<
"Identity not found.";
295 sendErrorReply(SIGNOND_IDENTITY_NOT_FOUND_ERR_NAME,
296 SIGNOND_IDENTITY_NOT_FOUND_ERR_STR);
300 BLAME() <<
"Password is not stored.";
301 sendErrorReply(SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_NAME,
302 SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_STR);
307 setDelayedReply(
true);
310 QVariantMap uiRequest;
311 uiRequest.unite(params);
312 uiRequest.insert(SSOUI_KEY_QUERYPASSWORD,
true);
313 uiRequest.insert(SSOUI_KEY_USERNAME, info.
userName());
314 uiRequest.insert(SSOUI_KEY_CAPTION, info.
caption());
316 queryUserPassword(uiRequest, connection(), message());
328 sendErrorReply(SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_NAME,
329 SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_STR +
330 QLatin1String(
"Database querying error occurred."));
347 TRACE() <<
"Error occurred while inserting/updating credentials.";
348 sendErrorReply(SIGNOND_REMOVE_FAILED_ERR_NAME,
349 SIGNOND_REMOVE_FAILED_ERR_STR +
350 QLatin1String(
"Database error occurred."));
353 setDelayedReply(
true);
358 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
359 this, SLOT(removeCompleted(QDBusPendingCallWatcher*)));
363 void SignonIdentity::removeCompleted(QDBusPendingCallWatcher *call)
365 Q_ASSERT(call != NULL);
372 QDBusPendingReply<> signOnUiReply = *call;
373 bool ok = !signOnUiReply.isError();
374 TRACE() << (ok ?
"removeIdentityData succeeded" :
"removeIdentityData failed");
378 QDBusMessage reply = context->message().createReply();
379 context->connection().send(reply);
384 TRACE() <<
"Signout request. Identity ID: " <<
id();
393 if (
id() != SIGNOND_NEW_IDENTITY) {
398 TRACE() <<
"clear data failed";
401 setDelayedReply(
true);
406 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
407 this, SLOT(signOutCompleted(QDBusPendingCallWatcher*)));
413 void SignonIdentity::signOutCompleted(QDBusPendingCallWatcher *call)
415 Q_ASSERT(call != NULL);
422 QDBusPendingReply<> signOnUiReply = *call;
423 bool ok = !signOnUiReply.isError();
424 TRACE() << (ok ?
"removeIdentityData succeeded" :
"removeIdentityData failed");
428 QDBusMessage reply = context->message().createReply();
430 context->connection().send(reply);
438 QString secret = info.value(SIGNOND_IDENTITY_INFO_SECRET).toString();
439 const QDBusContext &context =
static_cast<QDBusContext
>(*this);
442 context.connection(),
445 bool storeSecret = info.value(SIGNOND_IDENTITY_INFO_STORESECRET).toBool();
446 QVariant container = info.value(SIGNOND_IDENTITY_INFO_AUTHMETHODS);
448 qdbus_cast<
MethodMap>(container.value<QDBusArgument>());
451 QStringList ownerList =
452 info.value(SIGNOND_IDENTITY_INFO_OWNER).toStringList();
454 ownerList.append(appId);
462 info.value(SIGNOND_IDENTITY_INFO_USERNAME).toString();
464 info.value(SIGNOND_IDENTITY_INFO_CAPTION).toString();
466 info.value(SIGNOND_IDENTITY_INFO_REALMS).toStringList();
467 QStringList accessControlList =
468 info.value(SIGNOND_IDENTITY_INFO_ACL).toStringList();
469 int type = info.value(SIGNOND_IDENTITY_INFO_TYPE).toInt();
484 if (m_id == SIGNOND_NEW_IDENTITY) {
485 sendErrorReply(SIGNOND_STORE_FAILED_ERR_NAME,
486 SIGNOND_STORE_FAILED_ERR_STR);
496 BLAME() <<
"NULL database handler object.";
497 return SIGNOND_NEW_IDENTITY;
500 bool newIdentity = info.
isNew();
509 m_id = SIGNOND_NEW_IDENTITY;
511 TRACE() <<
"Error occurred while inserting/updating credentials.";
519 TRACE() <<
"FRESH, JUST STORED CREDENTIALS ID:" << m_id;
520 emit
infoUpdated((
int)SignOn::IdentityDataUpdated);
528 Q_ASSERT(call != NULL);
534 const QDBusMessage &message = context->message();
535 const QDBusConnection &connection = context->connection();
537 QDBusMessage errReply;
538 QDBusPendingReply<QVariantMap> reply = *call;
541 QVariantMap resultParameters;
542 if (!reply.isError() && reply.count()) {
543 resultParameters = reply.argumentAt<0>();
545 errReply = message.createErrorReply(
546 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME,
547 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR);
548 connection.send(errReply);
552 if (!resultParameters.contains(SSOUI_KEY_ERROR)) {
554 errReply = message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
555 SIGNOND_INTERNAL_SERVER_ERR_STR);
556 connection.send(errReply);
560 int errorCode = resultParameters.value(SSOUI_KEY_ERROR).toInt();
561 TRACE() <<
"error: " << errorCode;
562 if (errorCode != QUERY_ERROR_NONE) {
563 if (errorCode == QUERY_ERROR_CANCELED)
565 message.createErrorReply(
566 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME,
567 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR);
570 message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
571 QString(QLatin1String(
"signon-ui call returned error %1")).
574 connection.send(errReply);
578 if (resultParameters.contains(SSOUI_KEY_PASSWORD)) {
582 BLAME() <<
"NULL database handler object.";
583 errReply = message.createErrorReply(SIGNOND_STORE_FAILED_ERR_NAME,
584 SIGNOND_STORE_FAILED_ERR_STR);
585 connection.send(errReply);
591 m_pInfo->
setPassword(resultParameters[SSOUI_KEY_PASSWORD].toString());
596 if (ret != SIGNOND_NEW_IDENTITY) {
597 QDBusMessage dbusreply = message.createReply();
598 dbusreply << quint32(m_id);
599 connection.send(dbusreply);
602 BLAME() <<
"Error during update";
608 errReply = message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
609 SIGNOND_INTERNAL_SERVER_ERR_STR);
610 connection.send(errReply);
617 Q_ASSERT(call != NULL);
623 const QDBusMessage &message = context->message();
624 const QDBusConnection &connection = context->connection();
626 QDBusMessage errReply;
627 QDBusPendingReply<QVariantMap> reply = *call;
629 QVariantMap resultParameters;
630 if (!reply.isError() && reply.count()) {
631 resultParameters = reply.argumentAt<0>();
634 message.createErrorReply(
635 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME,
636 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR);
637 connection.send(errReply);
641 if (!resultParameters.contains(SSOUI_KEY_ERROR)) {
643 errReply = message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
644 SIGNOND_INTERNAL_SERVER_ERR_STR);
645 connection.send(errReply);
649 int errorCode = resultParameters.value(SSOUI_KEY_ERROR).toInt();
650 TRACE() <<
"error: " << errorCode;
651 if (errorCode != QUERY_ERROR_NONE) {
652 if (errorCode == QUERY_ERROR_CANCELED)
653 errReply = message.createErrorReply(
654 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME,
655 SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR);
656 else if (errorCode == QUERY_ERROR_FORGOT_PASSWORD)
657 errReply = message.createErrorReply(
658 SIGNOND_FORGOT_PASSWORD_ERR_NAME,
659 SIGNOND_FORGOT_PASSWORD_ERR_STR);
661 errReply = message.createErrorReply(
662 SIGNOND_INTERNAL_SERVER_ERR_NAME,
663 QString(QLatin1String(
"signon-ui call "
664 "returned error %1")).
667 connection.send(errReply);
671 if (resultParameters.contains(SSOUI_KEY_PASSWORD)) {
675 BLAME() <<
"NULL database handler object.";
676 errReply = message.createErrorReply(SIGNOND_STORE_FAILED_ERR_NAME,
677 SIGNOND_STORE_FAILED_ERR_STR);
678 connection.send(errReply);
685 m_pInfo->
password() == resultParameters[SSOUI_KEY_PASSWORD].
688 if (!ret && resultParameters.contains(SSOUI_KEY_CONFIRMCOUNT)) {
689 int count = resultParameters[SSOUI_KEY_CONFIRMCOUNT].toInt();
690 TRACE() <<
"retry count:" << count;
692 resultParameters[SSOUI_KEY_CONFIRMCOUNT] = (count-1);
693 resultParameters[SSOUI_KEY_MESSAGEID] =
694 QUERY_MESSAGE_NOT_AUTHORIZED;
695 queryUserPassword(resultParameters, connection, message);
703 QDBusMessage dbusreply = message.createReply();
705 connection.send(dbusreply);
710 errReply = message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
711 SIGNOND_INTERNAL_SERVER_ERR_STR);
712 connection.send(errReply);
718 #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)
void setType(const int type)
SignOn::CredentialsDBError lastError() const
bool verifySecret(const QString &secret)
void setCaption(const QString &caption)
void setOwnerList(const QStringList &owner)
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)
void setAccessControlList(const QStringList &acl)
QDBusPendingCall queryDialog(const QVariantMap ¶meters)
bool removeReference(const quint32 id, const QString &token, const QString &reference=QString())
const QString internalServerErrStr
QDBusPendingCall removeIdentityData(quint32 id)
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 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...