32 #include "SignOn/uisessiondata_priv.h" 33 #include "SignOn/authpluginif.h" 34 #include "SignOn/signonerror.h" 36 #define MAX_IDLE_TIME SIGNOND_MAX_IDLE_TIME 40 #define IDLE_WATCHDOG_TIMEOUT SIGNOND_MAX_IDLE_TIME * 500 42 #define SSO_KEY_USERNAME QLatin1String("UserName") 43 #define SSO_KEY_PASSWORD QLatin1String("Secret") 44 #define SSO_KEY_CAPTION QLatin1String("Caption") 57 static QVariantMap filterVariantMap(
const QVariantMap &other)
61 foreach(QString key, other.keys()) {
62 if (!other.value(key).isNull() && other.value(key).isValid())
63 result.insert(key, other.value(key));
69 static QString sessionName(
const quint32
id,
const QString &method)
71 return QString::number(
id) + QLatin1String(
"+") + method;
75 const QString &method,
81 m_requestIsActive(false),
85 m_queryCredsUiDisplayed(false)
89 QDBusConnection::sessionBus());
112 QString key = sessionName(
id, method);
115 if (sessionsOfStoredCredentials.contains(key)) {
116 return sessionsOfStoredCredentials.value(key);
125 TRACE() <<
"The resulted object is corrupted and has to be deleted";
131 sessionsOfStoredCredentials.insert(key, ssc);
133 sessionsOfNonStoredCredentials.append(ssc);
135 TRACE() <<
"The new session is created :" << key;
158 TRACE() <<
"Plugin of type " << m_method <<
" cannot be found";
163 SIGNAL(processResultReply(
const QVariantMap&)),
165 SLOT(processResultReply(
const QVariantMap&)),
166 Qt::DirectConnection);
169 SIGNAL(processStore(
const QVariantMap&)),
171 SLOT(processStore(
const QVariantMap&)),
172 Qt::DirectConnection);
175 SIGNAL(processUiRequest(
const QVariantMap&)),
177 SLOT(processUiRequest(
const QVariantMap&)),
178 Qt::DirectConnection);
181 SIGNAL(processRefreshRequest(
const QVariantMap&)),
183 SLOT(processRefreshRequest(
const QVariantMap&)),
184 Qt::DirectConnection);
187 SIGNAL(processError(
int,
const QString&)),
189 SLOT(processError(
int,
const QString&)),
190 Qt::DirectConnection);
195 SLOT(stateChangedSlot(
int,
const QString&)),
196 Qt::DirectConnection);
203 qDeleteAll(sessionsOfStoredCredentials);
204 sessionsOfStoredCredentials.clear();
206 qDeleteAll(sessionsOfNonStoredCredentials);
207 sessionsOfNonStoredCredentials.clear();
222 return QStringList();
230 if (!wantedMechanisms.size())
234 intersect(wantedMechanisms.toSet()).toList();
238 const QDBusMessage &message,
239 const QVariantMap &sessionDataVa,
240 const QString &mechanism,
241 const QString &cancelKey)
251 QMetaObject::invokeMethod(
this,
"startNewRequest", Qt::QueuedConnection);
259 for (requestIndex = 0;
260 requestIndex < m_listOfRequests.size();
262 if (m_listOfRequests.at(requestIndex).m_cancelKey == cancelKey)
266 TRACE() <<
"The request is found with index " << requestIndex;
268 if (requestIndex < m_listOfRequests.size()) {
271 bool isActive = (requestIndex == 0) && m_requestIsActive;
276 if (m_watcher && !m_watcher->isFinished()) {
290 m_listOfRequests.head() :
291 m_listOfRequests.takeAt(requestIndex));
293 QDBusMessage errReply =
294 rd.
m_msg.createErrorReply(SIGNOND_SESSION_CANCELED_ERR_NAME,
295 SIGNOND_SESSION_CANCELED_ERR_STR);
296 rd.m_conn.send(errReply);
297 TRACE() <<
"Size of the queue is" << m_listOfRequests.size();
311 key = sessionName(m_id, m_method);
312 sessionsOfNonStoredCredentials.append(
313 sessionsOfStoredCredentials.take(key));
315 key = sessionName(
id, m_method);
316 if (sessionsOfStoredCredentials.contains(key)) {
317 qCritical() <<
"attempt to assign existing id";
321 sessionsOfNonStoredCredentials.removeOne(
this);
322 sessionsOfStoredCredentials[key] =
this;
327 void SignonSessionCore::startProcess()
330 TRACE() <<
"the number of requests is" << m_listOfRequests.length();
332 m_requestIsActive =
true;
334 QVariantMap parameters = data.
m_params;
338 m_clientData = parameters;
346 if (info.
id() != SIGNOND_NEW_IDENTITY) {
356 QStringList paramsTokenList;
359 foreach(QString acl, identityAclList) {
361 isPeerAllowedToAccess(data.
m_conn, data.
m_msg, acl))
362 paramsTokenList.append(acl);
365 if (!paramsTokenList.isEmpty()) {
366 parameters[SSO_ACCESS_CONTROL_TOKENS] = paramsTokenList;
369 BLAME() <<
"Error occurred while getting data from credentials " 373 QVariantMap storedParams = db->
loadData(m_id, m_method);
379 if (parameters.contains(SSOUI_KEY_UIPOLICY)
380 && parameters[SSOUI_KEY_UIPOLICY] == RequestPasswordPolicy) {
390 QDBusMessage errReply =
391 data.
m_msg.createErrorReply(SIGNOND_RUNTIME_ERR_NAME,
392 SIGNOND_RUNTIME_ERR_STR);
393 data.
m_conn.send(errReply);
396 stateChangedSlot(SignOn::SessionStarted,
397 QLatin1String(
"The request is started successfully"));
400 void SignonSessionCore::replyError(
const QDBusConnection &conn,
401 const QDBusMessage &msg,
402 int err,
const QString &message)
410 if( err < Error::AuthSessionErr) {
411 BLAME() <<
"Deprecated error code:" << err;
412 if (message.isEmpty())
413 errMessage = SIGNOND_UNKNOWN_ERR_STR;
415 errMessage = message;
416 errName = SIGNOND_UNKNOWN_ERR_NAME;
419 if (Error::AuthSessionErr < err && err < Error::UserErr) {
421 case Error::MechanismNotAvailable:
422 errName = SIGNOND_MECHANISM_NOT_AVAILABLE_ERR_NAME;
423 errMessage = SIGNOND_MECHANISM_NOT_AVAILABLE_ERR_STR;
425 case Error::MissingData:
426 errName = SIGNOND_MISSING_DATA_ERR_NAME;
427 errMessage = SIGNOND_MISSING_DATA_ERR_STR;
429 case Error::InvalidCredentials:
430 errName = SIGNOND_INVALID_CREDENTIALS_ERR_NAME;
431 errMessage = SIGNOND_INVALID_CREDENTIALS_ERR_STR;
433 case Error::NotAuthorized:
434 errName = SIGNOND_NOT_AUTHORIZED_ERR_NAME;
435 errMessage = SIGNOND_NOT_AUTHORIZED_ERR_STR;
437 case Error::WrongState:
438 errName = SIGNOND_WRONG_STATE_ERR_NAME;
439 errMessage = SIGNOND_WRONG_STATE_ERR_STR;
441 case Error::OperationNotSupported:
442 errName = SIGNOND_OPERATION_NOT_SUPPORTED_ERR_NAME;
443 errMessage = SIGNOND_OPERATION_NOT_SUPPORTED_ERR_STR;
445 case Error::NoConnection:
446 errName = SIGNOND_NO_CONNECTION_ERR_NAME;
447 errMessage = SIGNOND_NO_CONNECTION_ERR_STR;
450 errName = SIGNOND_NETWORK_ERR_NAME;
451 errMessage = SIGNOND_NETWORK_ERR_STR;
454 errName = SIGNOND_SSL_ERR_NAME;
455 errMessage = SIGNOND_SSL_ERR_STR;
458 errName = SIGNOND_RUNTIME_ERR_NAME;
459 errMessage = SIGNOND_RUNTIME_ERR_STR;
461 case Error::SessionCanceled:
462 errName = SIGNOND_SESSION_CANCELED_ERR_NAME;
463 errMessage = SIGNOND_SESSION_CANCELED_ERR_STR;
465 case Error::TimedOut:
466 errName = SIGNOND_TIMED_OUT_ERR_NAME;
467 errMessage = SIGNOND_TIMED_OUT_ERR_STR;
469 case Error::UserInteraction:
470 errName = SIGNOND_USER_INTERACTION_ERR_NAME;
471 errMessage = SIGNOND_USER_INTERACTION_ERR_STR;
473 case Error::OperationFailed:
474 errName = SIGNOND_OPERATION_FAILED_ERR_NAME;
475 errMessage = SIGNOND_OPERATION_FAILED_ERR_STR;
477 case Error::EncryptionFailure:
478 errName = SIGNOND_ENCRYPTION_FAILED_ERR_NAME;
479 errMessage = SIGNOND_ENCRYPTION_FAILED_ERR_STR;
481 case Error::TOSNotAccepted:
482 errName = SIGNOND_TOS_NOT_ACCEPTED_ERR_NAME;
483 errMessage = SIGNOND_TOS_NOT_ACCEPTED_ERR_STR;
485 case Error::ForgotPassword:
486 errName = SIGNOND_FORGOT_PASSWORD_ERR_NAME;
487 errMessage = SIGNOND_FORGOT_PASSWORD_ERR_STR;
489 case Error::IncorrectDate:
490 errName = SIGNOND_INCORRECT_DATE_ERR_NAME;
491 errMessage = SIGNOND_INCORRECT_DATE_ERR_STR;
494 if (message.isEmpty())
495 errMessage = SIGNOND_UNKNOWN_ERR_STR;
497 errMessage = message;
498 errName = SIGNOND_UNKNOWN_ERR_NAME;
503 if (err > Error::UserErr) {
504 errName = SIGNOND_USER_ERROR_ERR_NAME;
505 errMessage = (QString::fromLatin1(
"%1:%2")).arg(err).arg(message);
508 QDBusMessage errReply;
509 errReply = msg.createErrorReply(errName,
510 (message.isEmpty() ? errMessage : message));
514 void SignonSessionCore::processStoreOperation(
const StoreOperation &operation)
516 TRACE() <<
"Processing store operation.";
522 BLAME() <<
"Error occured while updating credentials.";
525 TRACE() <<
"Processing --- StoreOperation::Blob";
530 BLAME() <<
"Error occured while storing data.";
535 void SignonSessionCore::requestDone()
537 m_listOfRequests.removeFirst();
538 m_requestIsActive =
false;
539 QMetaObject::invokeMethod(
this,
"startNewRequest", Qt::QueuedConnection);
542 void SignonSessionCore::processResultReply(
const QVariantMap &data)
548 if (m_listOfRequests.isEmpty())
554 QVariantList arguments;
555 QVariantMap filteredData = filterVariantMap(data);
563 if (m_id != SIGNOND_NEW_IDENTITY) {
565 bool identityWasValidated = info.
validated();
569 if (!info.
validated() && !m_tmpUsername.isEmpty()) {
572 if (!m_tmpPassword.isEmpty()) {
579 processStoreOperation(storeOp);
590 if (m_queryCredsUiDisplayed) {
595 event->m_sender =
static_cast<QObject *
>(
this);
597 QCoreApplication::postEvent(
600 Qt::HighEventPriority);
605 m_tmpUsername.clear();
606 m_tmpPassword.clear();
609 if (m_method != QLatin1String(
"password")
613 arguments << filteredData;
616 if (m_watcher && !m_watcher->isFinished()) {
621 m_queryCredsUiDisplayed =
false;
627 void SignonSessionCore::processStore(
const QVariantMap &data)
632 if (m_id == SIGNOND_NEW_IDENTITY) {
633 BLAME() <<
"Cannot store without identity";
636 QVariantMap filteredData = data;
640 filteredData.remove(SSO_ACCESS_CONTROL_TOKENS);
644 Q_ASSERT(db != NULL);
649 processStoreOperation(storeOp);
659 if (m_queryCredsUiDisplayed) {
660 TRACE() <<
"Secure storage not available.";
665 event->m_sender =
static_cast<QObject *
>(
this);
667 QCoreApplication::postEvent(
670 Qt::HighEventPriority);
674 m_queryCredsUiDisplayed =
false;
679 void SignonSessionCore::processUiRequest(
const QVariantMap &data)
685 if (!m_canceled && !m_listOfRequests.isEmpty()) {
690 if (!m_watcher->isFinished())
697 request.
m_params = filterVariantMap(data);
698 request.
m_params[SSOUI_KEY_REQUESTID] = uiRequestId;
700 if (m_id == SIGNOND_NEW_IDENTITY)
701 request.
m_params[SSOUI_KEY_STORED_IDENTITY] =
false;
703 request.
m_params[SSOUI_KEY_STORED_IDENTITY] =
true;
704 request.
m_params[SSOUI_KEY_IDENTITY] = m_id;
705 request.
m_params[SSOUI_KEY_CLIENT_DATA] = m_clientData;
706 request.
m_params[SSOUI_KEY_METHOD] = m_method;
723 TRACE() <<
"Caption missing";
724 if (m_id != SIGNOND_NEW_IDENTITY) {
739 TRACE() <<
"Secrets DB not available." 740 <<
"CAM has no keys available. Informing signon-ui.";
741 request.
m_params[SSOUI_KEY_STORAGE_KEYS_UNAVAILABLE] =
true;
745 m_watcher =
new QDBusPendingCallWatcher(
748 connect(m_watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
749 this, SLOT(queryUiSlot(QDBusPendingCallWatcher*)));
753 void SignonSessionCore::processRefreshRequest(
const QVariantMap &data)
759 if (!m_canceled && !m_listOfRequests.isEmpty()) {
760 QString uiRequestId = m_listOfRequests.head().m_cancelKey;
763 if (!m_watcher->isFinished())
770 m_listOfRequests.head().m_params = filterVariantMap(data);
771 m_watcher =
new QDBusPendingCallWatcher(
774 connect(m_watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
775 this, SLOT(queryUiSlot(QDBusPendingCallWatcher*)));
779 void SignonSessionCore::processError(
int err,
const QString &message)
783 m_tmpUsername.clear();
784 m_tmpPassword.clear();
786 if (m_listOfRequests.isEmpty())
794 if (m_watcher && !m_watcher->isFinished()) {
804 void SignonSessionCore::stateChangedSlot(
int state,
const QString &message)
806 if (!m_canceled && !m_listOfRequests.isEmpty()) {
818 else if (ce->removed())
830 TRACE() <<
"Custom event received.";
832 TRACE() <<
"Secure storage is available.";
834 TRACE() <<
"Secure storage still not available.";
837 QObject::customEvent(event);
840 void SignonSessionCore::queryUiSlot(QDBusPendingCallWatcher *call)
844 QDBusPendingReply<QVariantMap> reply = *call;
845 bool isRequestToRefresh =
false;
846 Q_ASSERT_X(m_listOfRequests.size() != 0, __func__,
847 "queue of requests is empty");
850 if (!reply.isError() && reply.count()) {
851 QVariantMap resultParameters = reply.argumentAt<0>();
852 if (resultParameters.contains(SSOUI_KEY_REFRESH)) {
853 isRequestToRefresh =
true;
854 resultParameters.remove(SSOUI_KEY_REFRESH);
857 rd.m_params = resultParameters;
861 if (resultParameters.contains(SSOUI_KEY_ERROR)
862 && (resultParameters[SSOUI_KEY_ERROR] == QUERY_ERROR_CANCELED)) {
864 m_queryCredsUiDisplayed =
false;
866 m_queryCredsUiDisplayed =
true;
869 rd.m_params.insert(SSOUI_KEY_ERROR,
870 (
int)SignOn::QUERY_ERROR_NO_SIGNONUI);
877 QVariant()).toString();
879 QVariant()).toString();
881 if (isRequestToRefresh) {
882 TRACE() <<
"REFRESH IS REQUIRED";
884 rd.m_params.remove(SSOUI_KEY_REFRESH);
895 void SignonSessionCore::startNewRequest()
901 if (m_listOfRequests.isEmpty()) {
902 TRACE() <<
"No more requests to process";
908 if (m_requestIsActive) {
909 TRACE() <<
"One request is already active";
914 if (m_watcher && !m_watcher->isFinished()) {
915 TRACE() <<
"Some UI operation is still pending";
919 TRACE() <<
"Starting the authentication process";
926 if (m_requestIsActive ||
933 sessionsOfStoredCredentials.remove(sessionName(m_id, m_method));
935 sessionsOfNonStoredCredentials.removeOne(
this);
937 QObjectList authSessions;
938 while (authSessions = children(), !authSessions.isEmpty()) {
939 delete authSessions.first();
946 QMetaObject::invokeMethod(
this,
"startNewRequest", Qt::QueuedConnection);
void process(const QDBusConnection &connection, const QDBusMessage &message, const QVariantMap &sessionDataVa, const QString &mechanism, const QString &cancelKey)
static PluginProxy * createNewPluginProxy(const QString &type)
QList< SignonSessionCore * > sessionsOfNonStoredCredentials
void credentialsSystemReady()
Base class for server objects that can be automatically destroyed after a certain period of inactivit...
virtual ~SignonSessionCore()
void customEvent(QEvent *event)
QStringList accessControlList() const
QString appIdOfPeer(const QDBusConnection &peerConnection, const QDBusMessage &peerMessage)
Looks up for the application identifier of a specific client process.
bool processRefresh(const QVariantMap &inData)
Describes a credentials store operatation.
Daemon side representation of authentication session.
void childEvent(QChildEvent *ce)
static AccessControlManagerHelper * instance()
void destroy()
Performs any predestruction operations and the destruction itself.
quint32 updateCredentials(const SignonIdentityInfo &info)
bool process(const QVariantMap &inData, const QString &mechanism)
bool storeData(const quint32 id, const QString &method, const QVariantMap &data)
QMap< QString, SignonSessionCore * > sessionsOfStoredCredentials
QDBusPendingCall refreshDialog(const QVariantMap ¶meters)
SignonIdentityInfo m_info
Any object in the signon framework that needs the CredentialsAccessManager - CAM - secure storage in ...
QVariantMap loadData(const quint32 id, const QString &method)
static void destroyUnused()
Deletes all disposable object for which the inactivity time has elapsed.
void stateChanged(const QString &requestId, int state, const QString &message)
static CredentialsAccessManager * instance()
Returns CAM instance.
#define SIGNON_UI_SERVICE
void setPassword(const QString &password)
QStringList queryAvailableMechanisms(const QStringList &wantedMechanisms)
#define SIGNON_SECURE_STORAGE_AVAILABLE
The CAM will reply with an event of this type when the secure storage access will be successfully res...
SignonIdentityInfo credentials(const quint32 id, bool queryPassword=true)
QStringList mechanisms() const
void cancelUiRequest(const QString &requestId)
static void stopAllAuthSessions()
Main singleton and manager object of the credentials database system.
#define SIGNON_SECURE_STORAGE_NOT_AVAILABLE
Use this event type to signal the CAM when the secure storage is not available.
QDBusPendingCall queryDialog(const QVariantMap ¶meters)
bool processUi(const QVariantMap &inData)
static pid_t pidOfPeer(const QDBusContext &peerContext)
int authSessionTimeout() const
static SignonSessionCore * sessionCore(const quint32 id, const QString &method, SignonDaemon *parent)
bool keysAvailable() const
The CAM manages the encryption keys collection.
static QStringList loadedPluginMethods(const QString &method)
QVariantMap mergeVariantMaps(const QVariantMap &map1, const QVariantMap &map2)
Helper method which unites two variant maps.
Daemon side representation of identity information.
CredentialsDB * credentialsDB() const
Manages the credentials I/O.
Helper class for access control-related functionality.
#define SIGNON_UI_DAEMON_OBJECTPATH
void setUserName(const QString &userName)
void setAutoDestruct(bool value=true) const
Mark the object as used.
Contains helper functions related to Access Control.
void keepInUse() const
Mark the object as used.
void cancel(const QString &cancelKey)
void setValidated(bool validated)
SignonSessionCore(quint32 id, const QString &method, int timeout, QObject *parent)