33 #include "SignOn/uisessiondata_priv.h"
34 #include "SignOn/authpluginif.h"
35 #include "SignOn/signonerror.h"
37 #define MAX_IDLE_TIME SIGNOND_MAX_IDLE_TIME
41 #define IDLE_WATCHDOG_TIMEOUT SIGNOND_MAX_IDLE_TIME * 500
43 #define SSO_KEY_USERNAME QLatin1String("UserName")
44 #define SSO_KEY_PASSWORD QLatin1String("Secret")
45 #define SSO_KEY_CAPTION QLatin1String("Caption")
47 using namespace SignonDaemonNS;
58 static QVariantMap filterVariantMap(
const QVariantMap &other)
62 foreach(QString key, other.keys()) {
63 if (!other.value(key).isNull() && other.value(key).isValid())
64 result.insert(key, other.value(key));
70 static QString sessionName(
const quint32
id,
const QString &method)
72 return QString::number(
id) + QLatin1String(
"+") + method;
76 const QString &method,
80 m_requestIsActive(false),
84 m_queryCredsUiDisplayed(false)
91 QDBusConnection::sessionBus());
111 const QString &method,
115 QString key = sessionName(
id, method);
128 TRACE() <<
"The resulted object is corrupted and has to be deleted";
138 TRACE() <<
"The new session is created :" << key;
161 TRACE() <<
"Plugin of type " << m_method <<
" cannot be found";
166 SIGNAL(processResultReply(
const QVariantMap&)),
168 SLOT(processResultReply(
const QVariantMap&)),
169 Qt::DirectConnection);
172 SIGNAL(processStore(
const QVariantMap&)),
174 SLOT(processStore(
const QVariantMap&)),
175 Qt::DirectConnection);
178 SIGNAL(processUiRequest(
const QVariantMap&)),
180 SLOT(processUiRequest(
const QVariantMap&)),
181 Qt::DirectConnection);
184 SIGNAL(processRefreshRequest(
const QVariantMap&)),
186 SLOT(processRefreshRequest(
const QVariantMap&)),
187 Qt::DirectConnection);
190 SIGNAL(processError(
int,
const QString&)),
192 SLOT(processError(
int,
const QString&)),
193 Qt::DirectConnection);
198 SLOT(stateChangedSlot(
int,
const QString&)),
199 Qt::DirectConnection);
225 return QStringList();
233 if (!wantedMechanisms.size())
237 intersect(wantedMechanisms.toSet()).toList();
241 const QDBusMessage &message,
242 const QVariantMap &sessionDataVa,
243 const QString &mechanism,
244 const QString &cancelKey)
254 QMetaObject::invokeMethod(
this,
"startNewRequest", Qt::QueuedConnection);
262 for (requestIndex = 0;
263 requestIndex < m_listOfRequests.size();
265 if (m_listOfRequests.at(requestIndex).m_cancelKey == cancelKey)
269 TRACE() <<
"The request is found with index " << requestIndex;
271 if (requestIndex < m_listOfRequests.size()) {
274 bool isActive = (requestIndex == 0) && m_requestIsActive;
279 if (m_watcher && !m_watcher->isFinished()) {
293 m_listOfRequests.head() :
294 m_listOfRequests.takeAt(requestIndex));
296 QDBusMessage errReply =
297 rd.
m_msg.createErrorReply(SIGNOND_SESSION_CANCELED_ERR_NAME,
298 SIGNOND_SESSION_CANCELED_ERR_STR);
299 rd.m_conn.send(errReply);
300 TRACE() <<
"Size of the queue is " << m_listOfRequests.size();
314 key = sessionName(m_id, m_method);
318 key = sessionName(
id, m_method);
320 qCritical() <<
"attempt to assign existing id";
330 void SignonSessionCore::startProcess()
333 TRACE() <<
"the number of requests is : " << m_listOfRequests.length();
337 m_requestIsActive =
true;
339 QVariantMap parameters = data.
m_params;
343 m_clientData = parameters;
351 if (info.
id() != SIGNOND_NEW_IDENTITY) {
361 QStringList paramsTokenList;
364 foreach(QString acl, identityAclList)
366 paramsTokenList.append(acl);
368 if (!paramsTokenList.isEmpty()) {
369 parameters[SSO_ACCESS_CONTROL_TOKENS] = paramsTokenList;
372 BLAME() <<
"Error occurred while getting data from credentials "
376 QVariantMap storedParams = db->
loadData(m_id, m_method);
382 if (parameters.contains(SSOUI_KEY_UIPOLICY)
383 && parameters[SSOUI_KEY_UIPOLICY] == RequestPasswordPolicy) {
393 QDBusMessage errReply =
394 data.
m_msg.createErrorReply(SIGNOND_RUNTIME_ERR_NAME,
395 SIGNOND_RUNTIME_ERR_STR);
396 data.
m_conn.send(errReply);
399 stateChangedSlot(SignOn::SessionStarted,
400 QLatin1String(
"The request is started successfully"));
403 void SignonSessionCore::replyError(
const QDBusConnection &conn,
404 const QDBusMessage &msg,
405 int err,
const QString &message)
413 if( err < Error::AuthSessionErr) {
414 BLAME() <<
"Deprecated error code: " << err;
415 if (message.isEmpty())
416 errMessage = SIGNOND_UNKNOWN_ERR_STR;
418 errMessage = message;
419 errName = SIGNOND_UNKNOWN_ERR_NAME;
422 if (Error::AuthSessionErr < err && err < Error::UserErr) {
424 case Error::MechanismNotAvailable:
425 errName = SIGNOND_MECHANISM_NOT_AVAILABLE_ERR_NAME;
426 errMessage = SIGNOND_MECHANISM_NOT_AVAILABLE_ERR_STR;
428 case Error::MissingData:
429 errName = SIGNOND_MISSING_DATA_ERR_NAME;
430 errMessage = SIGNOND_MISSING_DATA_ERR_STR;
432 case Error::InvalidCredentials:
433 errName = SIGNOND_INVALID_CREDENTIALS_ERR_NAME;
434 errMessage = SIGNOND_INVALID_CREDENTIALS_ERR_STR;
436 case Error::NotAuthorized:
437 errName = SIGNOND_NOT_AUTHORIZED_ERR_NAME;
438 errMessage = SIGNOND_NOT_AUTHORIZED_ERR_STR;
440 case Error::WrongState:
441 errName = SIGNOND_WRONG_STATE_ERR_NAME;
442 errMessage = SIGNOND_WRONG_STATE_ERR_STR;
444 case Error::OperationNotSupported:
445 errName = SIGNOND_OPERATION_NOT_SUPPORTED_ERR_NAME;
446 errMessage = SIGNOND_OPERATION_NOT_SUPPORTED_ERR_STR;
448 case Error::NoConnection:
449 errName = SIGNOND_NO_CONNECTION_ERR_NAME;
450 errMessage = SIGNOND_NO_CONNECTION_ERR_STR;
453 errName = SIGNOND_NETWORK_ERR_NAME;
454 errMessage = SIGNOND_NETWORK_ERR_STR;
457 errName = SIGNOND_SSL_ERR_NAME;
458 errMessage = SIGNOND_SSL_ERR_STR;
461 errName = SIGNOND_RUNTIME_ERR_NAME;
462 errMessage = SIGNOND_RUNTIME_ERR_STR;
464 case Error::SessionCanceled:
465 errName = SIGNOND_SESSION_CANCELED_ERR_NAME;
466 errMessage = SIGNOND_SESSION_CANCELED_ERR_STR;
468 case Error::TimedOut:
469 errName = SIGNOND_TIMED_OUT_ERR_NAME;
470 errMessage = SIGNOND_TIMED_OUT_ERR_STR;
472 case Error::UserInteraction:
473 errName = SIGNOND_USER_INTERACTION_ERR_NAME;
474 errMessage = SIGNOND_USER_INTERACTION_ERR_STR;
476 case Error::OperationFailed:
477 errName = SIGNOND_OPERATION_FAILED_ERR_NAME;
478 errMessage = SIGNOND_OPERATION_FAILED_ERR_STR;
480 case Error::EncryptionFailure:
481 errName = SIGNOND_ENCRYPTION_FAILED_ERR_NAME;
482 errMessage = SIGNOND_ENCRYPTION_FAILED_ERR_STR;
484 case Error::TOSNotAccepted:
485 errName = SIGNOND_TOS_NOT_ACCEPTED_ERR_NAME;
486 errMessage = SIGNOND_TOS_NOT_ACCEPTED_ERR_STR;
488 case Error::ForgotPassword:
489 errName = SIGNOND_FORGOT_PASSWORD_ERR_NAME;
490 errMessage = SIGNOND_FORGOT_PASSWORD_ERR_STR;
492 case Error::IncorrectDate:
493 errName = SIGNOND_INCORRECT_DATE_ERR_NAME;
494 errMessage = SIGNOND_INCORRECT_DATE_ERR_STR;
497 if (message.isEmpty())
498 errMessage = SIGNOND_UNKNOWN_ERR_STR;
500 errMessage = message;
501 errName = SIGNOND_UNKNOWN_ERR_NAME;
506 if (err > Error::UserErr) {
507 errName = SIGNOND_USER_ERROR_ERR_NAME;
508 errMessage = (QString::fromLatin1(
"%1:%2")).arg(err).arg(message);
511 QDBusMessage errReply;
512 errReply = msg.createErrorReply(errName,
513 (message.isEmpty() ? errMessage : message));
517 void SignonSessionCore::processStoreOperation(
const StoreOperation &operation)
519 TRACE() <<
"Processing store operation.";
525 BLAME() <<
"Error occured while updating credentials.";
528 TRACE() <<
"Processing --- StoreOperation::Blob";
533 BLAME() <<
"Error occured while storing data.";
538 void SignonSessionCore::requestDone()
540 m_listOfRequests.removeFirst();
541 m_requestIsActive =
false;
542 QMetaObject::invokeMethod(
this,
"startNewRequest", Qt::QueuedConnection);
545 void SignonSessionCore::processResultReply(
const QVariantMap &data)
551 if (m_listOfRequests.isEmpty())
557 QVariantList arguments;
558 QVariantMap filteredData = filterVariantMap(data);
566 if (m_id != SIGNOND_NEW_IDENTITY) {
568 bool identityWasValidated = info.
validated();
572 if (!info.
validated() && !m_tmpUsername.isEmpty()) {
575 if (!m_tmpPassword.isEmpty()) {
581 storeOp.m_info = info;
582 processStoreOperation(storeOp);
593 if (m_queryCredsUiDisplayed) {
598 event->m_sender =
static_cast<QObject *
>(
this);
600 QCoreApplication::postEvent(
603 Qt::HighEventPriority);
608 m_tmpUsername.clear();
609 m_tmpPassword.clear();
612 if (m_method != QLatin1String(
"password")
616 arguments << filteredData;
619 if (m_watcher && !m_watcher->isFinished()) {
624 m_queryCredsUiDisplayed =
false;
630 void SignonSessionCore::processStore(
const QVariantMap &data)
635 if (m_id == SIGNOND_NEW_IDENTITY) {
636 BLAME() <<
"Cannot store without identity";
639 QVariantMap filteredData = data;
643 filteredData.remove(SSO_ACCESS_CONTROL_TOKENS);
647 Q_ASSERT(db != NULL);
650 storeOp.m_blobData = filteredData;
651 storeOp.m_authMethod = m_method;
652 processStoreOperation(storeOp);
662 if (m_queryCredsUiDisplayed) {
663 TRACE() <<
"Secure storage not available.";
668 event->m_sender =
static_cast<QObject *
>(
this);
670 QCoreApplication::postEvent(
673 Qt::HighEventPriority);
677 m_queryCredsUiDisplayed =
false;
682 void SignonSessionCore::processUiRequest(
const QVariantMap &data)
688 if (!m_canceled && !m_listOfRequests.isEmpty()) {
693 if (!m_watcher->isFinished())
700 request.
m_params = filterVariantMap(data);
701 request.
m_params[SSOUI_KEY_REQUESTID] = uiRequestId;
703 if (m_id == SIGNOND_NEW_IDENTITY)
704 request.
m_params[SSOUI_KEY_STORED_IDENTITY] =
false;
706 request.
m_params[SSOUI_KEY_STORED_IDENTITY] =
true;
707 request.
m_params[SSOUI_KEY_IDENTITY] = m_id;
708 request.
m_params[SSOUI_KEY_CLIENT_DATA] = m_clientData;
709 request.
m_params[SSOUI_KEY_METHOD] = m_method;
719 TRACE() <<
"Caption missing";
720 if (m_id != SIGNOND_NEW_IDENTITY) {
735 TRACE() <<
"Secrets DB not available."
736 <<
"CAM has no keys available. Informing signon-ui.";
737 request.
m_params[SSOUI_KEY_STORAGE_KEYS_UNAVAILABLE] =
true;
741 m_watcher =
new QDBusPendingCallWatcher(
744 connect(m_watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
745 this, SLOT(queryUiSlot(QDBusPendingCallWatcher*)));
749 void SignonSessionCore::processRefreshRequest(
const QVariantMap &data)
755 if (!m_canceled && !m_listOfRequests.isEmpty()) {
756 QString uiRequestId = m_listOfRequests.head().m_cancelKey;
759 if (!m_watcher->isFinished())
766 m_listOfRequests.head().m_params = filterVariantMap(data);
767 m_watcher =
new QDBusPendingCallWatcher(
770 connect(m_watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
771 this, SLOT(queryUiSlot(QDBusPendingCallWatcher*)));
775 void SignonSessionCore::processError(
int err,
const QString &message)
779 m_tmpUsername.clear();
780 m_tmpPassword.clear();
782 if (m_listOfRequests.isEmpty())
790 if (m_watcher && !m_watcher->isFinished()) {
800 void SignonSessionCore::stateChangedSlot(
int state,
const QString &message)
802 if (!m_canceled && !m_listOfRequests.isEmpty()) {
814 else if (ce->removed())
826 TRACE() <<
"Custom event received.";
828 TRACE() <<
"Secure storage is available.";
830 TRACE() <<
"Secure storage still not available.";
833 QObject::customEvent(event);
836 void SignonSessionCore::queryUiSlot(QDBusPendingCallWatcher *call)
840 QDBusPendingReply<QVariantMap> reply = *call;
841 bool isRequestToRefresh =
false;
842 Q_ASSERT_X(m_listOfRequests.size() != 0, __func__,
843 "queue of requests is empty");
845 if (!reply.isError() && reply.count()) {
846 QVariantMap resultParameters = reply.argumentAt<0>();
847 if (resultParameters.contains(SSOUI_KEY_REFRESH)) {
848 isRequestToRefresh =
true;
849 resultParameters.remove(SSOUI_KEY_REFRESH);
852 m_listOfRequests.head().m_params = resultParameters;
856 if (resultParameters.contains(SSOUI_KEY_ERROR)
857 && (resultParameters[SSOUI_KEY_ERROR] == QUERY_ERROR_CANCELED)) {
859 m_queryCredsUiDisplayed =
false;
861 m_queryCredsUiDisplayed =
true;
864 m_listOfRequests.head().m_params.insert(SSOUI_KEY_ERROR,
865 (
int)SignOn::QUERY_ERROR_NO_SIGNONUI);
871 m_tmpUsername = m_listOfRequests.head().m_params.value(
873 m_tmpPassword = m_listOfRequests.head().m_params.value(
876 if (isRequestToRefresh) {
877 TRACE() <<
"REFRESH IS REQUIRED";
879 m_listOfRequests.head().m_params.remove(SSOUI_KEY_REFRESH);
882 m_plugin->
processUi(m_listOfRequests.head().m_params);
890 void SignonSessionCore::startNewRequest()
897 if (!m_listOfRequests.length()) {
898 TRACE() <<
"the data queue is EMPTY!!!";
903 if (m_requestIsActive) {
904 TRACE() <<
"One request is already active";
909 if (m_watcher && !m_watcher->isFinished()) {
910 TRACE() <<
"watcher is in running mode";
914 TRACE() <<
"Start the authentication process";
920 if (m_requestIsActive ||
937 QMetaObject::invokeMethod(
this,
"startNewRequest", Qt::QueuedConnection);