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,
82 m_queryCredsUiDisplayed(false)
89 QDBusConnection::sessionBus());
109 const QString &method,
113 QString key = sessionName(
id, method);
126 TRACE() <<
"The resulted object is corrupted and has to be deleted";
136 TRACE() <<
"The new session is created :" << key;
159 TRACE() <<
"Plugin of type " << m_method <<
" cannot be found";
164 SIGNAL(processResultReply(
const QString&,
const QVariantMap&)),
166 SLOT(processResultReply(
const QString&,
const QVariantMap&)),
167 Qt::DirectConnection);
170 SIGNAL(processStore(
const QString&,
const QVariantMap&)),
172 SLOT(processStore(
const QString&,
const QVariantMap&)),
173 Qt::DirectConnection);
176 SIGNAL(processUiRequest(
const QString&,
const QVariantMap&)),
178 SLOT(processUiRequest(
const QString&,
const QVariantMap&)),
179 Qt::DirectConnection);
182 SIGNAL(processRefreshRequest(
const QString&,
const QVariantMap&)),
184 SLOT(processRefreshRequest(
const QString&,
const QVariantMap&)),
185 Qt::DirectConnection);
188 SIGNAL(processError(
const QString&,
int,
const QString&)),
190 SLOT(processError(
const QString&,
int,
const QString&)),
191 Qt::DirectConnection);
194 SIGNAL(
stateChanged(
const QString&,
int,
const QString&)),
196 SLOT(stateChangedSlot(
const QString&,
int,
const QString&)),
197 Qt::DirectConnection);
223 return QStringList();
231 if (!wantedMechanisms.size())
235 intersect(wantedMechanisms.toSet()).toList();
239 const QDBusMessage &message,
240 const QVariantMap &sessionDataVa,
241 const QString &mechanism,
242 const QString &cancelKey)
252 QMetaObject::invokeMethod(
this,
"startNewRequest", Qt::QueuedConnection);
260 for (requestIndex = 0;
261 requestIndex < m_listOfRequests.size();
263 if (m_listOfRequests.at(requestIndex).m_cancelKey == cancelKey)
267 TRACE() <<
"The request is found with index " << requestIndex;
269 if (requestIndex < m_listOfRequests.size()) {
270 if (requestIndex == 0) {
271 m_canceled = cancelKey;
274 if (m_watcher && !m_watcher->isFinished()) {
288 m_listOfRequests.head() :
289 m_listOfRequests.takeAt(requestIndex)));
291 QDBusMessage errReply =
292 rd.
m_msg.createErrorReply(SIGNOND_SESSION_CANCELED_ERR_NAME,
293 SIGNOND_SESSION_CANCELED_ERR_STR);
295 TRACE() <<
"Size of the queue is " << m_listOfRequests.size();
309 key = sessionName(m_id, m_method);
313 key = sessionName(
id, m_method);
315 qCritical() <<
"attempt to assign existing id";
325 void SignonSessionCore::startProcess()
328 TRACE() <<
"the number of requests is : " << m_listOfRequests.length();
333 QVariantMap parameters = data.
m_params;
337 m_clientData = parameters;
345 if (info.
id() != SIGNOND_NEW_IDENTITY) {
355 QStringList paramsTokenList;
358 foreach(QString acl, identityAclList)
360 paramsTokenList.append(acl);
362 if (!paramsTokenList.isEmpty()) {
363 parameters[SSO_ACCESS_CONTROL_TOKENS] = paramsTokenList;
366 BLAME() <<
"Error occurred while getting data from credentials "
370 QVariantMap storedParams = db->
loadData(m_id, m_method);
376 if (parameters.contains(SSOUI_KEY_UIPOLICY)
377 && parameters[SSOUI_KEY_UIPOLICY] == RequestPasswordPolicy) {
387 QDBusMessage errReply =
388 data.
m_msg.createErrorReply(SIGNOND_RUNTIME_ERR_NAME,
389 SIGNOND_RUNTIME_ERR_STR);
390 data.
m_conn.send(errReply);
391 m_listOfRequests.removeFirst();
392 QMetaObject::invokeMethod(
this,
"startNewRequest", Qt::QueuedConnection);
394 stateChangedSlot(data.
m_cancelKey, SignOn::SessionStarted,
395 QLatin1String(
"The request is started successfully"));
398 void SignonSessionCore::replyError(
const QDBusConnection &conn,
399 const QDBusMessage &msg,
400 int err,
const QString &message)
408 if( err < Error::AuthSessionErr) {
409 BLAME() <<
"Deprecated error code: " << err;
410 if (message.isEmpty())
411 errMessage = SIGNOND_UNKNOWN_ERR_STR;
413 errMessage = message;
414 errName = SIGNOND_UNKNOWN_ERR_NAME;
417 if (Error::AuthSessionErr < err && err < Error::UserErr) {
419 case Error::MechanismNotAvailable:
420 errName = SIGNOND_MECHANISM_NOT_AVAILABLE_ERR_NAME;
421 errMessage = SIGNOND_MECHANISM_NOT_AVAILABLE_ERR_STR;
423 case Error::MissingData:
424 errName = SIGNOND_MISSING_DATA_ERR_NAME;
425 errMessage = SIGNOND_MISSING_DATA_ERR_STR;
427 case Error::InvalidCredentials:
428 errName = SIGNOND_INVALID_CREDENTIALS_ERR_NAME;
429 errMessage = SIGNOND_INVALID_CREDENTIALS_ERR_STR;
431 case Error::NotAuthorized:
432 errName = SIGNOND_NOT_AUTHORIZED_ERR_NAME;
433 errMessage = SIGNOND_NOT_AUTHORIZED_ERR_STR;
435 case Error::WrongState:
436 errName = SIGNOND_WRONG_STATE_ERR_NAME;
437 errMessage = SIGNOND_WRONG_STATE_ERR_STR;
439 case Error::OperationNotSupported:
440 errName = SIGNOND_OPERATION_NOT_SUPPORTED_ERR_NAME;
441 errMessage = SIGNOND_OPERATION_NOT_SUPPORTED_ERR_STR;
443 case Error::NoConnection:
444 errName = SIGNOND_NO_CONNECTION_ERR_NAME;
445 errMessage = SIGNOND_NO_CONNECTION_ERR_STR;
448 errName = SIGNOND_NETWORK_ERR_NAME;
449 errMessage = SIGNOND_NETWORK_ERR_STR;
452 errName = SIGNOND_SSL_ERR_NAME;
453 errMessage = SIGNOND_SSL_ERR_STR;
456 errName = SIGNOND_RUNTIME_ERR_NAME;
457 errMessage = SIGNOND_RUNTIME_ERR_STR;
459 case Error::SessionCanceled:
460 errName = SIGNOND_SESSION_CANCELED_ERR_NAME;
461 errMessage = SIGNOND_SESSION_CANCELED_ERR_STR;
463 case Error::TimedOut:
464 errName = SIGNOND_TIMED_OUT_ERR_NAME;
465 errMessage = SIGNOND_TIMED_OUT_ERR_STR;
467 case Error::UserInteraction:
468 errName = SIGNOND_USER_INTERACTION_ERR_NAME;
469 errMessage = SIGNOND_USER_INTERACTION_ERR_STR;
471 case Error::OperationFailed:
472 errName = SIGNOND_OPERATION_FAILED_ERR_NAME;
473 errMessage = SIGNOND_OPERATION_FAILED_ERR_STR;
475 case Error::EncryptionFailure:
476 errName = SIGNOND_ENCRYPTION_FAILED_ERR_NAME;
477 errMessage = SIGNOND_ENCRYPTION_FAILED_ERR_STR;
479 case Error::TOSNotAccepted:
480 errName = SIGNOND_TOS_NOT_ACCEPTED_ERR_NAME;
481 errMessage = SIGNOND_TOS_NOT_ACCEPTED_ERR_STR;
483 case Error::ForgotPassword:
484 errName = SIGNOND_FORGOT_PASSWORD_ERR_NAME;
485 errMessage = SIGNOND_FORGOT_PASSWORD_ERR_STR;
487 case Error::IncorrectDate:
488 errName = SIGNOND_INCORRECT_DATE_ERR_NAME;
489 errMessage = SIGNOND_INCORRECT_DATE_ERR_STR;
492 if (message.isEmpty())
493 errMessage = SIGNOND_UNKNOWN_ERR_STR;
495 errMessage = message;
496 errName = SIGNOND_UNKNOWN_ERR_NAME;
501 if (err > Error::UserErr) {
502 errName = SIGNOND_USER_ERROR_ERR_NAME;
503 errMessage = (QString::fromLatin1(
"%1:%2")).arg(err).arg(message);
506 QDBusMessage errReply;
507 errReply = msg.createErrorReply(errName,
508 (message.isEmpty() ? errMessage : message));
512 void SignonSessionCore::processStoreOperation(
const StoreOperation &operation)
514 TRACE() <<
"Processing store operation.";
520 BLAME() <<
"Error occured while updating credentials.";
523 TRACE() <<
"Processing --- StoreOperation::Blob";
528 BLAME() <<
"Error occured while storing data.";
533 void SignonSessionCore::processResultReply(
const QString &cancelKey,
534 const QVariantMap &data)
540 if (!m_listOfRequests.size())
545 if (cancelKey != m_canceled) {
546 QVariantList arguments;
547 QVariantMap filteredData = filterVariantMap(data);
555 if (m_id != SIGNOND_NEW_IDENTITY) {
557 bool identityWasValidated = info.
validated();
561 if (!info.
validated() && !m_tmpUsername.isEmpty()) {
564 if (!m_tmpPassword.isEmpty()) {
570 storeOp.m_info = info;
571 processStoreOperation(storeOp);
582 if (m_queryCredsUiDisplayed) {
587 event->m_sender =
static_cast<QObject *
>(
this);
589 QCoreApplication::postEvent(
592 Qt::HighEventPriority);
597 m_tmpUsername.clear();
598 m_tmpPassword.clear();
601 if (m_method != QLatin1String(
"password")
605 arguments << filteredData;
608 m_canceled = QString();
610 if (m_watcher && !m_watcher->isFinished()) {
615 m_queryCredsUiDisplayed =
false;
617 m_canceled = QString();
618 QMetaObject::invokeMethod(
this,
"startNewRequest", Qt::QueuedConnection);
621 void SignonSessionCore::processStore(
const QString &cancelKey,
622 const QVariantMap &data)
628 if (m_id == SIGNOND_NEW_IDENTITY) {
629 BLAME() <<
"Cannot store without identity";
632 QVariantMap filteredData = data;
636 filteredData.remove(SSO_ACCESS_CONTROL_TOKENS);
640 Q_ASSERT(db != NULL);
643 storeOp.m_blobData = filteredData;
644 storeOp.m_authMethod = m_method;
645 processStoreOperation(storeOp);
655 if (m_queryCredsUiDisplayed) {
656 TRACE() <<
"Secure storage not available.";
661 event->m_sender =
static_cast<QObject *
>(
this);
663 QCoreApplication::postEvent(
666 Qt::HighEventPriority);
670 m_queryCredsUiDisplayed =
false;
675 void SignonSessionCore::processUiRequest(
const QString &cancelKey,
676 const QVariantMap &data)
682 if (cancelKey != m_canceled && m_listOfRequests.size()) {
683 QString uiRequestId = m_listOfRequests.head().m_cancelKey;
686 if (!m_watcher->isFinished())
693 m_listOfRequests.head().m_params = filterVariantMap(data);
694 m_listOfRequests.head().m_params[SSOUI_KEY_REQUESTID] = uiRequestId;
696 if (m_id == SIGNOND_NEW_IDENTITY)
697 m_listOfRequests.head().m_params[SSOUI_KEY_STORED_IDENTITY] =
false;
699 m_listOfRequests.head().m_params[SSOUI_KEY_STORED_IDENTITY] =
true;
700 m_listOfRequests.head().m_params[SSOUI_KEY_IDENTITY] = m_id;
701 m_listOfRequests.head().m_params[SSOUI_KEY_CLIENT_DATA] = m_clientData;
710 TRACE() <<
"Caption missing";
711 if (m_id != SIGNOND_NEW_IDENTITY) {
727 TRACE() <<
"Secrets DB not available."
728 <<
"CAM has no keys available. Informing signon-ui.";
729 m_listOfRequests.head().m_params[
730 SSOUI_KEY_STORAGE_KEYS_UNAVAILABLE] =
true;
734 m_watcher =
new QDBusPendingCallWatcher(
735 m_signonui->
queryDialog(m_listOfRequests.head().m_params),
737 connect(m_watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
738 this, SLOT(queryUiSlot(QDBusPendingCallWatcher*)));
742 void SignonSessionCore::processRefreshRequest(
const QString &cancelKey,
743 const QVariantMap &data)
749 if (cancelKey != m_canceled && m_listOfRequests.size()) {
750 QString uiRequestId = m_listOfRequests.head().m_cancelKey;
753 if (!m_watcher->isFinished())
760 m_listOfRequests.head().m_params = filterVariantMap(data);
761 m_watcher =
new QDBusPendingCallWatcher(
764 connect(m_watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
765 this, SLOT(queryUiSlot(QDBusPendingCallWatcher*)));
769 void SignonSessionCore::processError(
const QString &cancelKey,
770 int err,
const QString &message)
774 m_tmpUsername.clear();
775 m_tmpPassword.clear();
777 if (!m_listOfRequests.size())
782 if (cancelKey != m_canceled) {
785 if (m_watcher && !m_watcher->isFinished()) {
792 m_canceled = QString();
793 QMetaObject::invokeMethod(
this,
"startNewRequest", Qt::QueuedConnection);
796 void SignonSessionCore::stateChangedSlot(
const QString &cancelKey,
797 int state,
const QString &message)
799 if (cancelKey != m_canceled && m_listOfRequests.size()) {
811 else if (ce->removed())
823 TRACE() <<
"Custom event received.";
825 TRACE() <<
"Secure storage is available.";
827 TRACE() <<
"Secure storage still not available.";
833 void SignonSessionCore::queryUiSlot(QDBusPendingCallWatcher *call)
837 QDBusPendingReply<QVariantMap> reply = *call;
838 bool isRequestToRefresh =
false;
839 Q_ASSERT_X(m_listOfRequests.size() != 0, __func__,
840 "queue of requests is empty");
842 if (!reply.isError() && reply.count()) {
843 QVariantMap resultParameters = reply.argumentAt<0>();
844 if (resultParameters.contains(SSOUI_KEY_REFRESH)) {
845 isRequestToRefresh =
true;
846 resultParameters.remove(SSOUI_KEY_REFRESH);
849 m_listOfRequests.head().m_params = resultParameters;
853 if (resultParameters.contains(SSOUI_KEY_ERROR)
854 && (resultParameters[SSOUI_KEY_ERROR] == QUERY_ERROR_CANCELED)) {
856 m_queryCredsUiDisplayed =
false;
858 m_queryCredsUiDisplayed =
true;
861 m_listOfRequests.head().m_params.insert(SSOUI_KEY_ERROR,
862 (
int)SignOn::QUERY_ERROR_NO_SIGNONUI);
865 if (m_listOfRequests.head().m_cancelKey != m_canceled) {
868 m_tmpUsername = m_listOfRequests.head().m_params.value(
870 m_tmpPassword = m_listOfRequests.head().m_params.value(
873 if (isRequestToRefresh) {
874 TRACE() <<
"REFRESH IS REQUIRED";
876 m_listOfRequests.head().m_params.remove(SSOUI_KEY_REFRESH);
878 m_listOfRequests.head().m_params);
880 m_plugin->
processUi(m_listOfRequests.head().m_cancelKey,
881 m_listOfRequests.head().m_params);
889 void SignonSessionCore::startNewRequest()
894 if (!m_listOfRequests.length()) {
895 TRACE() <<
"the data queue is EMPTY!!!";
901 TRACE() <<
" the plugin is in challenge processing";
906 if (m_watcher && !m_watcher->isFinished()) {
907 TRACE() <<
"watcher is in running mode";
911 TRACE() <<
"Start the authentication process";
934 QMetaObject::invokeMethod(
this,
"startNewRequest", Qt::QueuedConnection);