signon 8.54

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

signonsessioncore.cpp
Go to the documentation of this file.
1 /*
2 * This file is part of signon
3 *
4 * Copyright (C) 2009-2010 Nokia Corporation.
5 * Copyright (C) 2011 Intel Corporation.
6 *
7 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
8 * Contact: Jussi Laako <jussi.laako@linux.intel.com>
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public License
12 * version 2.1 as published by the Free Software Foundation.
13 *
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 */
24
25 #include "signond-common.h"
26 #include "signonauthsession.h"
27 #include "signonidentityinfo.h"
28 #include "signonidentity.h"
29 #include "signonui_interface.h"
30 #include "accesscontrolmanagerhelper.h"
31
32 #include "SignOn/uisessiondata_priv.h"
33 #include "SignOn/authpluginif.h"
34 #include "SignOn/signonerror.h"
35
36 #define MAX_IDLE_TIME SIGNOND_MAX_IDLE_TIME
37 /*
38 * the watchdog searches for idle sessions with period of half of idle timeout
39 * */
40 #define IDLE_WATCHDOG_TIMEOUT SIGNOND_MAX_IDLE_TIME * 500
41
42 #define SSO_KEY_USERNAME QLatin1String("UserName")
43 #define SSO_KEY_PASSWORD QLatin1String("Secret")
44 #define SSO_KEY_CAPTION QLatin1String("Caption")
45
46 using namespace SignonDaemonNS;
47
48 /*
49 * cache of session queues, as was mentined they cannot be static
50 * */
51 QMap<QString, SignonSessionCore *> sessionsOfStoredCredentials;
52 /*
53 * List of "zero" authsessions, needed for global signout
54 * */
55 QList<SignonSessionCore *> sessionsOfNonStoredCredentials;
56
57 static QVariantMap filterVariantMap(const QVariantMap &other)
58 {
59 QVariantMap result;
60
61 foreach(QString key, other.keys()) {
62 if (!other.value(key).isNull() && other.value(key).isValid())
63 result.insert(key, other.value(key));
64 }
65
66 return result;
67 }
68
69 static QString sessionName(const quint32 id, const QString &method)
70 {
71 return QString::number(id) + QLatin1String("+") + method;
72 }
73
74 SignonSessionCore::SignonSessionCore(quint32 id,
75 const QString &method,
76 int timeout,
77 QObject *parent):
78 SignonDisposable(timeout, parent),
79 m_signonui(0),
80 m_watcher(0),
81 m_requestIsActive(false),
82 m_canceled(false),
83 m_id(id),
84 m_method(method),
85 m_queryCredsUiDisplayed(false)
86 {
87 m_signonui = new SignonUiAdaptor(SIGNON_UI_SERVICE,
88 SIGNON_UI_DAEMON_OBJECTPATH,
89 QDBusConnection::sessionBus());
90
91
92 connect(CredentialsAccessManager::instance(),
93 SIGNAL(credentialsSystemReady()),
94 SLOT(credentialsSystemReady()));
95 }
96
97 SignonSessionCore::~SignonSessionCore()
98 {
99 delete m_plugin;
100 delete m_watcher;
101 delete m_signonui;
102
103 m_plugin = NULL;
104 m_signonui = NULL;
105 m_watcher = NULL;
106 }
107
108 SignonSessionCore *SignonSessionCore::sessionCore(const quint32 id,
109 const QString &method,
110 SignonDaemon *parent)
111 {
112 QString key = sessionName(id, method);
113
114 if (id) {
115 if (sessionsOfStoredCredentials.contains(key)) {
116 return sessionsOfStoredCredentials.value(key);
117 }
118 }
119
120 SignonSessionCore *ssc = new SignonSessionCore(id, method,
121 parent->authSessionTimeout(),
122 parent);
123
124 if (ssc->setupPlugin() == false) {
125 TRACE() << "The resulted object is corrupted and has to be deleted";
126 delete ssc;
127 return NULL;
128 }
129
130 if (id)
131 sessionsOfStoredCredentials.insert(key, ssc);
132 else
133 sessionsOfNonStoredCredentials.append(ssc);
134
135 TRACE() << "The new session is created :" << key;
136 return ssc;
137 }
138
139 quint32 SignonSessionCore::id() const
140 {
141 TRACE();
142 keepInUse();
143 return m_id;
144 }
145
146 QString SignonSessionCore::method() const
147 {
148 TRACE();
149 keepInUse();
150 return m_method;
151 }
152
153 bool SignonSessionCore::setupPlugin()
154 {
155 m_plugin = PluginProxy::createNewPluginProxy(m_method);
156
157 if (!m_plugin) {
158 TRACE() << "Plugin of type " << m_method << " cannot be found";
159 return false;
160 }
161
162 connect(m_plugin,
163 SIGNAL(processResultReply(const QVariantMap&)),
164 this,
165 SLOT(processResultReply(const QVariantMap&)),
166 Qt::DirectConnection);
167
168 connect(m_plugin,
169 SIGNAL(processStore(const QVariantMap&)),
170 this,
171 SLOT(processStore(const QVariantMap&)),
172 Qt::DirectConnection);
173
174 connect(m_plugin,
175 SIGNAL(processUiRequest(const QVariantMap&)),
176 this,
177 SLOT(processUiRequest(const QVariantMap&)),
178 Qt::DirectConnection);
179
180 connect(m_plugin,
181 SIGNAL(processRefreshRequest(const QVariantMap&)),
182 this,
183 SLOT(processRefreshRequest(const QVariantMap&)),
184 Qt::DirectConnection);
185
186 connect(m_plugin,
187 SIGNAL(processError(int, const QString&)),
188 this,
189 SLOT(processError(int, const QString&)),
190 Qt::DirectConnection);
191
192 connect(m_plugin,
193 SIGNAL(stateChanged(int, const QString&)),
194 this,
195 SLOT(stateChangedSlot(int, const QString&)),
196 Qt::DirectConnection);
197
198 return true;
199 }
200
201 void SignonSessionCore::stopAllAuthSessions()
202 {
203 qDeleteAll(sessionsOfStoredCredentials);
204 sessionsOfStoredCredentials.clear();
205
206 qDeleteAll(sessionsOfNonStoredCredentials);
207 sessionsOfNonStoredCredentials.clear();
208 }
209
210 QStringList SignonSessionCore::loadedPluginMethods(const QString &method)
211 {
212 foreach (SignonSessionCore *corePtr, sessionsOfStoredCredentials) {
213 if (corePtr->method() == method)
214 return corePtr->queryAvailableMechanisms(QStringList());
215 }
216
217 foreach (SignonSessionCore *corePtr, sessionsOfNonStoredCredentials) {
218 if (corePtr->method() == method)
219 return corePtr->queryAvailableMechanisms(QStringList());
220 }
221
222 return QStringList();
223 }
224
225 QStringList
226 SignonSessionCore::queryAvailableMechanisms(const QStringList &wantedMechanisms)
227 {
228 keepInUse();
229
230 if (!wantedMechanisms.size())
231 return m_plugin->mechanisms();
232
233 return m_plugin->mechanisms().toSet().
234 intersect(wantedMechanisms.toSet()).toList();
235 }
236
237 void SignonSessionCore::process(const QDBusConnection &connection,
238 const QDBusMessage &message,
239 const QVariantMap &sessionDataVa,
240 const QString &mechanism,
241 const QString &cancelKey)
242 {
243 keepInUse();
244 m_listOfRequests.enqueue(RequestData(connection,
245 message,
246 sessionDataVa,
247 mechanism,
248 cancelKey));
249
250 if (CredentialsAccessManager::instance()->isCredentialsSystemReady())
251 QMetaObject::invokeMethod(this, "startNewRequest", Qt::QueuedConnection);
252 }
253
254 void SignonSessionCore::cancel(const QString &cancelKey)
255 {
256 TRACE();
257
258 int requestIndex;
259 for (requestIndex = 0;
260 requestIndex < m_listOfRequests.size();
261 requestIndex++) {
262 if (m_listOfRequests.at(requestIndex).m_cancelKey == cancelKey)
263 break;
264 }
265
266 TRACE() << "The request is found with index " << requestIndex;
267
268 if (requestIndex < m_listOfRequests.size()) {
269 /* If the request being cancelled is active, we need to keep
270 * in the queue until the plugin has replied. */
271 bool isActive = (requestIndex == 0) && m_requestIsActive;
272 if (isActive) {
273 m_canceled = true;
274 m_plugin->cancel();
275
276 if (m_watcher && !m_watcher->isFinished()) {
277 m_signonui->cancelUiRequest(cancelKey);
278 delete m_watcher;
279 m_watcher = 0;
280 }
281 }
282
283 /*
284 * We must let to the m_listOfRequests to have the canceled request data
285 * in order to delay the next request execution until the actual cancelation
286 * will happen. We will know about that precisely: plugin must reply via
287 * resultSlot or via errorSlot.
288 * */
289 RequestData rd(isActive ?
290 m_listOfRequests.head() :
291 m_listOfRequests.takeAt(requestIndex));
292
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();
298 }
299 }
300
301 void SignonSessionCore::setId(quint32 id)
302 {
303 keepInUse();
304
305 if (m_id == id)
306 return;
307
308 QString key;
309
310 if (id == 0) {
311 key = sessionName(m_id, m_method);
312 sessionsOfNonStoredCredentials.append(
313 sessionsOfStoredCredentials.take(key));
314 } else {
315 key = sessionName(id, m_method);
316 if (sessionsOfStoredCredentials.contains(key)) {
317 qCritical() << "attempt to assign existing id";
318 return;
319 }
320
321 sessionsOfNonStoredCredentials.removeOne(this);
322 sessionsOfStoredCredentials[key] = this;
323 }
324 m_id = id;
325 }
326
327 void SignonSessionCore::startProcess()
328 {
329
330 TRACE() << "the number of requests is" << m_listOfRequests.length();
331
332 m_requestIsActive = true;
333 RequestData data = m_listOfRequests.head();
334 QVariantMap parameters = data.m_params;
335
336 /* save the client data; this should not be modified during the processing
337 * of this request */
338 m_clientData = parameters;
339
340 if (m_id) {
341 CredentialsDB *db =
342 CredentialsAccessManager::instance()->credentialsDB();
343 Q_ASSERT(db != 0);
344
345 SignonIdentityInfo info = db->credentials(m_id);
346 if (info.id() != SIGNOND_NEW_IDENTITY) {
347 if (!parameters.contains(SSO_KEY_PASSWORD)) {
348 parameters[SSO_KEY_PASSWORD] = info.password();
349 }
350 //database overrules over sessiondata for validated username,
351 //so that identity cannot be misused
352 if (info.validated() || !parameters.contains(SSO_KEY_USERNAME)) {
353 parameters[SSO_KEY_USERNAME] = info.userName();
354 }
355
356 QStringList paramsTokenList;
357 QStringList identityAclList = info.accessControlList();
358
359 foreach(QString acl, identityAclList) {
360 if (AccessControlManagerHelper::instance()->
361 isPeerAllowedToAccess(data.m_conn, data.m_msg, acl))
362 paramsTokenList.append(acl);
363 }
364
365 if (!paramsTokenList.isEmpty()) {
366 parameters[SSO_ACCESS_CONTROL_TOKENS] = paramsTokenList;
367 }
368 } else {
369 BLAME() << "Error occurred while getting data from credentials "
370 "database.";
371 }
372
373 QVariantMap storedParams = db->loadData(m_id, m_method);
374
375 //parameters will overwrite any common keys on stored params
376 parameters = mergeVariantMaps(storedParams, parameters);
377 }
378
379 if (parameters.contains(SSOUI_KEY_UIPOLICY)
380 && parameters[SSOUI_KEY_UIPOLICY] == RequestPasswordPolicy) {
381 parameters.remove(SSO_KEY_PASSWORD);
382 }
383
384 /* Temporary caching, if credentials are valid
385 * this data will be effectively cached */
386 m_tmpUsername = parameters[SSO_KEY_USERNAME].toString();
387 m_tmpPassword = parameters[SSO_KEY_PASSWORD].toString();
388
389 if (!m_plugin->process(parameters, data.m_mechanism)) {
390 QDBusMessage errReply =
391 data.m_msg.createErrorReply(SIGNOND_RUNTIME_ERR_NAME,
392 SIGNOND_RUNTIME_ERR_STR);
393 data.m_conn.send(errReply);
394 requestDone();
395 } else
396 stateChangedSlot(SignOn::SessionStarted,
397 QLatin1String("The request is started successfully"));
398 }
399
400 void SignonSessionCore::replyError(const QDBusConnection &conn,
401 const QDBusMessage &msg,
402 int err, const QString &message)
403 {
404 keepInUse();
405
406 QString errName;
407 QString errMessage;
408
409 //TODO this is needed for old error codes
410 if( err < Error::AuthSessionErr) {
411 BLAME() << "Deprecated error code:" << err;
412 if (message.isEmpty())
413 errMessage = SIGNOND_UNKNOWN_ERR_STR;
414 else
415 errMessage = message;
416 errName = SIGNOND_UNKNOWN_ERR_NAME;
417 }
418
419 if (Error::AuthSessionErr < err && err < Error::UserErr) {
420 switch(err) {
421 case Error::MechanismNotAvailable:
422 errName = SIGNOND_MECHANISM_NOT_AVAILABLE_ERR_NAME;
423 errMessage = SIGNOND_MECHANISM_NOT_AVAILABLE_ERR_STR;
424 break;
425 case Error::MissingData:
426 errName = SIGNOND_MISSING_DATA_ERR_NAME;
427 errMessage = SIGNOND_MISSING_DATA_ERR_STR;
428 break;
429 case Error::InvalidCredentials:
430 errName = SIGNOND_INVALID_CREDENTIALS_ERR_NAME;
431 errMessage = SIGNOND_INVALID_CREDENTIALS_ERR_STR;
432 break;
433 case Error::NotAuthorized:
434 errName = SIGNOND_NOT_AUTHORIZED_ERR_NAME;
435 errMessage = SIGNOND_NOT_AUTHORIZED_ERR_STR;
436 break;
437 case Error::WrongState:
438 errName = SIGNOND_WRONG_STATE_ERR_NAME;
439 errMessage = SIGNOND_WRONG_STATE_ERR_STR;
440 break;
441 case Error::OperationNotSupported:
442 errName = SIGNOND_OPERATION_NOT_SUPPORTED_ERR_NAME;
443 errMessage = SIGNOND_OPERATION_NOT_SUPPORTED_ERR_STR;
444 break;
445 case Error::NoConnection:
446 errName = SIGNOND_NO_CONNECTION_ERR_NAME;
447 errMessage = SIGNOND_NO_CONNECTION_ERR_STR;
448 break;
449 case Error::Network:
450 errName = SIGNOND_NETWORK_ERR_NAME;
451 errMessage = SIGNOND_NETWORK_ERR_STR;
452 break;
453 case Error::Ssl:
454 errName = SIGNOND_SSL_ERR_NAME;
455 errMessage = SIGNOND_SSL_ERR_STR;
456 break;
457 case Error::Runtime:
458 errName = SIGNOND_RUNTIME_ERR_NAME;
459 errMessage = SIGNOND_RUNTIME_ERR_STR;
460 break;
461 case Error::SessionCanceled:
462 errName = SIGNOND_SESSION_CANCELED_ERR_NAME;
463 errMessage = SIGNOND_SESSION_CANCELED_ERR_STR;
464 break;
465 case Error::TimedOut:
466 errName = SIGNOND_TIMED_OUT_ERR_NAME;
467 errMessage = SIGNOND_TIMED_OUT_ERR_STR;
468 break;
469 case Error::UserInteraction:
470 errName = SIGNOND_USER_INTERACTION_ERR_NAME;
471 errMessage = SIGNOND_USER_INTERACTION_ERR_STR;
472 break;
473 case Error::OperationFailed:
474 errName = SIGNOND_OPERATION_FAILED_ERR_NAME;
475 errMessage = SIGNOND_OPERATION_FAILED_ERR_STR;
476 break;
477 case Error::EncryptionFailure:
478 errName = SIGNOND_ENCRYPTION_FAILED_ERR_NAME;
479 errMessage = SIGNOND_ENCRYPTION_FAILED_ERR_STR;
480 break;
481 case Error::TOSNotAccepted:
482 errName = SIGNOND_TOS_NOT_ACCEPTED_ERR_NAME;
483 errMessage = SIGNOND_TOS_NOT_ACCEPTED_ERR_STR;
484 break;
485 case Error::ForgotPassword:
486 errName = SIGNOND_FORGOT_PASSWORD_ERR_NAME;
487 errMessage = SIGNOND_FORGOT_PASSWORD_ERR_STR;
488 break;
489 case Error::IncorrectDate:
490 errName = SIGNOND_INCORRECT_DATE_ERR_NAME;
491 errMessage = SIGNOND_INCORRECT_DATE_ERR_STR;
492 break;
493 default:
494 if (message.isEmpty())
495 errMessage = SIGNOND_UNKNOWN_ERR_STR;
496 else
497 errMessage = message;
498 errName = SIGNOND_UNKNOWN_ERR_NAME;
499 break;
500 };
501 }
502
503 if (err > Error::UserErr) {
504 errName = SIGNOND_USER_ERROR_ERR_NAME;
505 errMessage = (QString::fromLatin1("%1:%2")).arg(err).arg(message);
506 }
507
508 QDBusMessage errReply;
509 errReply = msg.createErrorReply(errName,
510 (message.isEmpty() ? errMessage : message));
511 conn.send(errReply);
512 }
513
514 void SignonSessionCore::processStoreOperation(const StoreOperation &operation)
515 {
516 TRACE() << "Processing store operation.";
517 CredentialsDB *db = CredentialsAccessManager::instance()->credentialsDB();
518 Q_ASSERT(db != 0);
519
520 if (operation.m_storeType != StoreOperation::Blob) {
521 if (!(db->updateCredentials(operation.m_info))) {
522 BLAME() << "Error occured while updating credentials.";
523 }
524 } else {
525 TRACE() << "Processing --- StoreOperation::Blob";
526
527 if (!db->storeData(m_id,
528 operation.m_authMethod,
529 operation.m_blobData)) {
530 BLAME() << "Error occured while storing data.";
531 }
532 }
533 }
534
535 void SignonSessionCore::requestDone()
536 {
537 m_listOfRequests.removeFirst();
538 m_requestIsActive = false;
539 QMetaObject::invokeMethod(this, "startNewRequest", Qt::QueuedConnection);
540 }
541
542 void SignonSessionCore::processResultReply(const QVariantMap &data)
543 {
544 TRACE();
545
546 keepInUse();
547
548 if (m_listOfRequests.isEmpty())
549 return;
550
551 RequestData rd = m_listOfRequests.head();
552
553 if (!m_canceled) {
554 QVariantList arguments;
555 QVariantMap filteredData = filterVariantMap(data);
556
557 CredentialsAccessManager *camManager =
558 CredentialsAccessManager::instance();
559 CredentialsDB *db = camManager->credentialsDB();
560 Q_ASSERT(db != 0);
561
562 //update database entry
563 if (m_id != SIGNOND_NEW_IDENTITY) {
564 SignonIdentityInfo info = db->credentials(m_id);
565 bool identityWasValidated = info.validated();
566
567 /* update username and password from ui interaction; do not allow
568 * updating the username if the identity is validated */
569 if (!info.validated() && !m_tmpUsername.isEmpty()) {
570 info.setUserName(m_tmpUsername);
571 }
572 if (!m_tmpPassword.isEmpty()) {
573 info.setPassword(m_tmpPassword);
574 }
575 info.setValidated(true);
576
577 StoreOperation storeOp(StoreOperation::Credentials);
578 storeOp.m_info = info;
579 processStoreOperation(storeOp);
580
581 /* If the credentials are validated, the secrets db is not
582 * available and not authorized keys are available, then
583 * the store operation has been performed on the memory
584 * cache only; inform the CAM about the situation. */
585 if (identityWasValidated && !db->isSecretsDBOpen()) {
586 /* Send the storage not available event only if the curent
587 * result processing is following a previous signon UI query.
588 * This is to avoid unexpected UI pop-ups. */
589
590 if (m_queryCredsUiDisplayed) {
591 SecureStorageEvent *event =
592 new SecureStorageEvent(
593 (QEvent::Type)SIGNON_SECURE_STORAGE_NOT_AVAILABLE);
594
595 event->m_sender = static_cast<QObject *>(this);
596
597 QCoreApplication::postEvent(
598 CredentialsAccessManager::instance(),
599 event,
600 Qt::HighEventPriority);
601 }
602 }
603 }
604
605 m_tmpUsername.clear();
606 m_tmpPassword.clear();
607
608 //remove secret field from output
609 if (m_method != QLatin1String("password")
610 && filteredData.contains(SSO_KEY_PASSWORD))
611 filteredData.remove(SSO_KEY_PASSWORD);
612
613 arguments << filteredData;
614 rd.m_conn.send(rd.m_msg.createReply(arguments));
615
616 if (m_watcher && !m_watcher->isFinished()) {
617 m_signonui->cancelUiRequest(rd.m_cancelKey);
618 delete m_watcher;
619 m_watcher = 0;
620 }
621 m_queryCredsUiDisplayed = false;
622 }
623
624 requestDone();
625 }
626
627 void SignonSessionCore::processStore(const QVariantMap &data)
628 {
629 TRACE();
630
631 keepInUse();
632 if (m_id == SIGNOND_NEW_IDENTITY) {
633 BLAME() << "Cannot store without identity";
634 return;
635 }
636 QVariantMap filteredData = data;
637 //do not store username or password
638 filteredData.remove(SSO_KEY_PASSWORD);
639 filteredData.remove(SSO_KEY_USERNAME);
640 filteredData.remove(SSO_ACCESS_CONTROL_TOKENS);
641
642 //store data into db
643 CredentialsDB *db = CredentialsAccessManager::instance()->credentialsDB();
644 Q_ASSERT(db != NULL);
645
646 StoreOperation storeOp(StoreOperation::Blob);
647 storeOp.m_blobData = filteredData;
648 storeOp.m_authMethod = m_method;
649 processStoreOperation(storeOp);
650
651 /* If the credentials are validated, the secrets db is not available and
652 * not authorized keys are available inform the CAM about the situation. */
653 SignonIdentityInfo info = db->credentials(m_id);
654 if (info.validated() && !db->isSecretsDBOpen()) {
655 /* Send the storage not available event only if the curent store
656 * processing is following a previous signon UI query. This is to avoid
657 * unexpected UI pop-ups.
658 */
659 if (m_queryCredsUiDisplayed) {
660 TRACE() << "Secure storage not available.";
661
662 SecureStorageEvent *event =
663 new SecureStorageEvent(
664 (QEvent::Type)SIGNON_SECURE_STORAGE_NOT_AVAILABLE);
665 event->m_sender = static_cast<QObject *>(this);
666
667 QCoreApplication::postEvent(
668 CredentialsAccessManager::instance(),
669 event,
670 Qt::HighEventPriority);
671 }
672 }
673
674 m_queryCredsUiDisplayed = false;
675
676 return;
677 }
678
679 void SignonSessionCore::processUiRequest(const QVariantMap &data)
680 {
681 TRACE();
682
683 keepInUse();
684
685 if (!m_canceled && !m_listOfRequests.isEmpty()) {
686 RequestData &request = m_listOfRequests.head();
687 QString uiRequestId = request.m_cancelKey;
688
689 if (m_watcher) {
690 if (!m_watcher->isFinished())
691 m_signonui->cancelUiRequest(uiRequestId);
692
693 delete m_watcher;
694 m_watcher = 0;
695 }
696
697 request.m_params = filterVariantMap(data);
698 request.m_params[SSOUI_KEY_REQUESTID] = uiRequestId;
699
700 if (m_id == SIGNOND_NEW_IDENTITY)
701 request.m_params[SSOUI_KEY_STORED_IDENTITY] = false;
702 else
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;
707 request.m_params[SSOUI_KEY_MECHANISM] = request.m_mechanism;
708
709 CredentialsAccessManager *camManager =
710 CredentialsAccessManager::instance();
711 CredentialsDB *db = camManager->credentialsDB();
712 Q_ASSERT(db != 0);
713
714 //check that we have caption
715 if (!data.contains(SSO_KEY_CAPTION)) {
716 TRACE() << "Caption missing";
717 if (m_id != SIGNOND_NEW_IDENTITY) {
718 SignonIdentityInfo info = db->credentials(m_id);
719 request.m_params.insert(SSO_KEY_CAPTION, info.caption());
720 TRACE() << "Got caption: " << info.caption();
721 }
722 }
723
724 /*
725 * Check the secure storage status, if any issues are encountered signal
726 * this to the signon ui. */
727 if (!db->isSecretsDBOpen()) {
728 TRACE();
729
730 //If there are no keys available
731 if (!camManager->keysAvailable()) {
732 TRACE() << "Secrets DB not available."
733 << "CAM has no keys available. Informing signon-ui.";
734 request.m_params[SSOUI_KEY_STORAGE_KEYS_UNAVAILABLE] = true;
735 }
736 }
737
738 m_watcher = new QDBusPendingCallWatcher(
739 m_signonui->queryDialog(request.m_params),
740 this);
741 connect(m_watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
742 this, SLOT(queryUiSlot(QDBusPendingCallWatcher*)));
743 }
744 }
745
746 void SignonSessionCore::processRefreshRequest(const QVariantMap &data)
747 {
748 TRACE();
749
750 keepInUse();
751
752 if (!m_canceled && !m_listOfRequests.isEmpty()) {
753 QString uiRequestId = m_listOfRequests.head().m_cancelKey;
754
755 if (m_watcher) {
756 if (!m_watcher->isFinished())
757 m_signonui->cancelUiRequest(uiRequestId);
758
759 delete m_watcher;
760 m_watcher = 0;
761 }
762
763 m_listOfRequests.head().m_params = filterVariantMap(data);
764 m_watcher = new QDBusPendingCallWatcher(
765 m_signonui->refreshDialog(m_listOfRequests.head().m_params),
766 this);
767 connect(m_watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
768 this, SLOT(queryUiSlot(QDBusPendingCallWatcher*)));
769 }
770 }
771
772 void SignonSessionCore::processError(int err, const QString &message)
773 {
774 TRACE();
775 keepInUse();
776 m_tmpUsername.clear();
777 m_tmpPassword.clear();
778
779 if (m_listOfRequests.isEmpty())
780 return;
781
782 RequestData rd = m_listOfRequests.head();
783
784 if (!m_canceled) {
785 replyError(rd.m_conn, rd.m_msg, err, message);
786
787 if (m_watcher && !m_watcher->isFinished()) {
788 m_signonui->cancelUiRequest(rd.m_cancelKey);
789 delete m_watcher;
790 m_watcher = 0;
791 }
792 }
793
794 requestDone();
795 }
796
797 void SignonSessionCore::stateChangedSlot(int state, const QString &message)
798 {
799 if (!m_canceled && !m_listOfRequests.isEmpty()) {
800 RequestData rd = m_listOfRequests.head();
801 emit stateChanged(rd.m_cancelKey, (int)state, message);
802 }
803
804 keepInUse();
805 }
806
807 void SignonSessionCore::childEvent(QChildEvent *ce)
808 {
809 if (ce->added())
810 keepInUse();
811 else if (ce->removed())
812 SignonDisposable::destroyUnused();
813 }
814
815 void SignonSessionCore::customEvent(QEvent *event)
816 {
817 /* TODO: This method is useless now, and there's probably a simpler
818 * way to handle the secure storage events than using QEvent (such
819 * as direct signal connections).
820 * For the time being, let this method live just for logging the
821 * secure storage events.
822 */
823 TRACE() << "Custom event received.";
824 if (event->type() == SIGNON_SECURE_STORAGE_AVAILABLE) {
825 TRACE() << "Secure storage is available.";
826 } else if (event->type() == SIGNON_SECURE_STORAGE_NOT_AVAILABLE) {
827 TRACE() << "Secure storage still not available.";
828 }
829
830 QObject::customEvent(event);
831 }
832
833 void SignonSessionCore::queryUiSlot(QDBusPendingCallWatcher *call)
834 {
835 keepInUse();
836
837 QDBusPendingReply<QVariantMap> reply = *call;
838 bool isRequestToRefresh = false;
839 Q_ASSERT_X(m_listOfRequests.size() != 0, __func__,
840 "queue of requests is empty");
841
842 RequestData &rd = m_listOfRequests.head();
843 if (!reply.isError() && reply.count()) {
844 QVariantMap resultParameters = reply.argumentAt<0>();
845 if (resultParameters.contains(SSOUI_KEY_REFRESH)) {
846 isRequestToRefresh = true;
847 resultParameters.remove(SSOUI_KEY_REFRESH);
848 }
849
850 rd.m_params = resultParameters;
851
852 /* If the query ui was canceled or any other error occurred
853 * do not set this flag to true. */
854 if (resultParameters.contains(SSOUI_KEY_ERROR)
855 && (resultParameters[SSOUI_KEY_ERROR] == QUERY_ERROR_CANCELED)) {
856
857 m_queryCredsUiDisplayed = false;
858 } else {
859 m_queryCredsUiDisplayed = true;
860 }
861 } else {
862 rd.m_params.insert(SSOUI_KEY_ERROR,
863 (int)SignOn::QUERY_ERROR_NO_SIGNONUI);
864 }
865
866 if (!m_canceled) {
867 /* Temporary caching, if credentials are valid
868 * this data will be effectively cached */
869 m_tmpUsername = rd.m_params.value(SSO_KEY_USERNAME,
870 QVariant()).toString();
871 m_tmpPassword = rd.m_params.value(SSO_KEY_PASSWORD,
872 QVariant()).toString();
873
874 if (isRequestToRefresh) {
875 TRACE() << "REFRESH IS REQUIRED";
876
877 rd.m_params.remove(SSOUI_KEY_REFRESH);
878 m_plugin->processRefresh(rd.m_params);
879 } else {
880 m_plugin->processUi(rd.m_params);
881 }
882 }
883
884 delete m_watcher;
885 m_watcher = NULL;
886 }
887
888 void SignonSessionCore::startNewRequest()
889 {
890 keepInUse();
891
892 m_canceled = false;
893
894 if (m_listOfRequests.isEmpty()) {
895 TRACE() << "No more requests to process";
896 setAutoDestruct(true);
897 return;
898 }
899
900 // there is an active request already
901 if (m_requestIsActive) {
902 TRACE() << "One request is already active";
903 return;
904 }
905
906 //there is some UI operation with plugin
907 if (m_watcher && !m_watcher->isFinished()) {
908 TRACE() << "Some UI operation is still pending";
909 return;
910 }
911
912 TRACE() << "Starting the authentication process";
913 setAutoDestruct(false);
914 startProcess();
915 }
916
917 void SignonSessionCore::destroy()
918 {
919 if (m_requestIsActive ||
920 m_watcher != NULL) {
921 keepInUse();
922 return;
923 }
924
925 if (m_id)
926 sessionsOfStoredCredentials.remove(sessionName(m_id, m_method));
927 else
928 sessionsOfNonStoredCredentials.removeOne(this);
929
930 emit destroyed();
931 deleteLater();
932 }
933
934 void SignonSessionCore::credentialsSystemReady()
935 {
936 QMetaObject::invokeMethod(this, "startNewRequest", Qt::QueuedConnection);
937 }
SignonDaemonNS::SignonSessionCore::process
void process(const QDBusConnection &connection, const QDBusMessage &message, const QVariantMap &sessionDataVa, const QString &mechanism, const QString &cancelKey)
Definition: signonsessioncore.cpp:237
SignonDaemonNS::StoreOperation::m_authMethod
QString m_authMethod
Definition: signonsessioncoretools.h:62
SignonDaemonNS::StoreOperation::m_storeType
StoreType m_storeType
Definition: signonsessioncoretools.h:59
SignonDaemonNS::PluginProxy::createNewPluginProxy
static PluginProxy * createNewPluginProxy(const QString &type)
Definition: pluginproxy.cpp:138
sessionsOfNonStoredCredentials
QList< SignonSessionCore * > sessionsOfNonStoredCredentials
Definition: signonsessioncore.cpp:55
SignonDaemonNS::SignonSessionCore::credentialsSystemReady
void credentialsSystemReady()
Definition: signonsessioncore.cpp:934
SignonDaemonNS::SignonDisposable
Base class for server objects that can be automatically destroyed after a certain period of inactivit...
Definition: signondisposable.h:39
SignonDaemonNS::StoreOperation::Credentials
Definition: signonsessioncoretools.h:50
SignonDaemonNS::SignonSessionCore::~SignonSessionCore
virtual ~SignonSessionCore()
Definition: signonsessioncore.cpp:97
SignonDaemonNS::SignonSessionCore::customEvent
void customEvent(QEvent *event)
Definition: signonsessioncore.cpp:815
SignonDaemonNS::RequestData::m_msg
QDBusMessage m_msg
Definition: signonsessioncoretools.h:84
SignonDaemonNS::SignonIdentityInfo::accessControlList
QStringList accessControlList() const
Definition: signonidentityinfo.h:94
SignonDaemonNS::RequestData::m_cancelKey
QString m_cancelKey
Definition: signonsessioncoretools.h:87
SignonDaemonNS::PluginProxy::processRefresh
bool processRefresh(const QVariantMap &inData)
Definition: pluginproxy.cpp:214
SignonDaemonNS::StoreOperation
Describes a credentials store operatation.
Definition: signonsessioncoretools.h:48
SignonDaemonNS::SignonSessionCore
Daemon side representation of authentication session.
Definition: signonsessioncore.h:50
BLAME
#define BLAME()
Definition: debug.h:32
SignonDaemonNS::SignonSessionCore::childEvent
void childEvent(QChildEvent *ce)
Definition: signonsessioncore.cpp:807
SignonDaemonNS::AccessControlManagerHelper::instance
static AccessControlManagerHelper * instance()
Definition: accesscontrolmanagerhelper.cpp:44
SSO_KEY_CAPTION
#define SSO_KEY_CAPTION
Definition: signonsessioncore.cpp:44
SignonDaemonNS::SignonSessionCore::destroy
void destroy()
Performs any predestruction operations and the destruction itself.
Definition: signonsessioncore.cpp:917
SignonDaemonNS::SignonIdentityInfo::caption
QString caption() const
Definition: signonidentityinfo.h:83
SignonDaemonNS::SignonSessionCore::id
quint32 id() const
Definition: signonsessioncore.cpp:139
SignonDaemonNS::SignonIdentityInfo::password
QString password() const
Definition: signonidentityinfo.h:76
SignonDaemonNS::SignonIdentityInfo::id
quint32 id() const
Definition: signonidentityinfo.h:68
SignonDaemonNS::CredentialsDB::updateCredentials
quint32 updateCredentials(const SignonIdentityInfo &info)
Definition: credentialsdb.cpp:1405
signond-common.h
SignonDaemonNS::PluginProxy::process
bool process(const QVariantMap &inData, const QString &mechanism)
Definition: pluginproxy.cpp:176
SignonDaemonNS::SignonDaemon
Daemon core.
Definition: signondaemon.h:105
SignonDaemonNS::CredentialsDB::storeData
bool storeData(const quint32 id, const QString &method, const QVariantMap &data)
Definition: credentialsdb.cpp:1469
sessionsOfStoredCredentials
QMap< QString, SignonSessionCore * > sessionsOfStoredCredentials
Definition: signonsessioncore.cpp:51
SignonDaemonNS::RequestData::m_mechanism
QString m_mechanism
Definition: signonsessioncoretools.h:86
SignonUiAdaptor::refreshDialog
QDBusPendingCall refreshDialog(const QVariantMap &parameters)
Definition: signonui_interface.cpp:61
signonidentityinfo.h
SignonDaemonNS::RequestData::m_conn
QDBusConnection m_conn
Definition: signonsessioncoretools.h:83
SignonDaemonNS::SignonIdentityInfo::userName
QString userName() const
Definition: signonidentityinfo.h:71
SignonDaemonNS::StoreOperation::m_info
SignonIdentityInfo m_info
Definition: signonsessioncoretools.h:60
SignonDaemonNS::SignonSessionCore::method
QString method() const
Definition: signonsessioncore.cpp:146
SignonDaemonNS::SecureStorageEvent
Any object in the signon framework that needs the CredentialsAccessManager - CAM - secure storage in ...
Definition: credentialsaccessmanager.h:91
SignonDaemonNS::CredentialsDB::loadData
QVariantMap loadData(const quint32 id, const QString &method)
Definition: credentialsdb.cpp:1451
SignonDaemonNS::SignonDisposable::destroyUnused
static void destroyUnused()
Deletes all disposable object for which the inactivity time has elapsed.
Definition: signondisposable.cpp:109
SignonDaemonNS::SignonSessionCore::stateChanged
void stateChanged(const QString &requestId, int state, const QString &message)
SignonDaemonNS::CredentialsAccessManager::instance
static CredentialsAccessManager * instance()
Returns CAM instance.
Definition: credentialsaccessmanager.cpp:160
SIGNON_UI_SERVICE
#define SIGNON_UI_SERVICE
Definition: signond-common.h:56
SignonDaemonNS::SignonIdentityInfo::setPassword
void setPassword(const QString &password)
Definition: signonidentityinfo.h:75
SignonDaemonNS::SignonSessionCore::queryAvailableMechanisms
QStringList queryAvailableMechanisms(const QStringList &wantedMechanisms)
Definition: signonsessioncore.cpp:226
SIGNON_SECURE_STORAGE_AVAILABLE
#define SIGNON_SECURE_STORAGE_AVAILABLE
The CAM will reply with an event of this type when the secure storage access will be successfully res...
Definition: credentialsaccessmanager.h:66
SignonDaemonNS::CredentialsDB::credentials
SignonIdentityInfo credentials(const quint32 id, bool queryPassword=true)
Definition: credentialsdb.cpp:1362
SignonDaemonNS::PluginProxy::mechanisms
QStringList mechanisms() const
Definition: pluginproxy.h:72
SignonDaemonNS::StoreOperation::m_blobData
QVariantMap m_blobData
Definition: signonsessioncoretools.h:63
SignonUiAdaptor
Definition: signonui_interface.h:41
SignonDaemonNS::CredentialsDB::isSecretsDBOpen
bool isSecretsDBOpen()
Definition: credentialsdb.cpp:1325
SignonUiAdaptor::cancelUiRequest
void cancelUiRequest(const QString &requestId)
Definition: signonui_interface.cpp:73
SignonDaemonNS::SignonSessionCore::stopAllAuthSessions
static void stopAllAuthSessions()
Definition: signonsessioncore.cpp:201
SSO_KEY_PASSWORD
#define SSO_KEY_PASSWORD
Definition: signonsessioncore.cpp:43
SignonDaemonNS::CredentialsAccessManager
Main singleton and manager object of the credentials database system.
Definition: credentialsaccessmanager.h:193
SIGNON_SECURE_STORAGE_NOT_AVAILABLE
#define SIGNON_SECURE_STORAGE_NOT_AVAILABLE
Use this event type to signal the CAM when the secure storage is not available.
Definition: credentialsaccessmanager.h:58
SignonUiAdaptor::queryDialog
QDBusPendingCall queryDialog(const QVariantMap &parameters)
Definition: signonui_interface.cpp:49
SignonDaemonNS::PluginProxy::processUi
bool processUi(const QVariantMap &inData)
Definition: pluginproxy.cpp:196
SignonDaemonNS::SignonDaemon::authSessionTimeout
int authSessionTimeout() const
Definition: signondaemon.cpp:610
SignonDaemonNS::SignonSessionCore::sessionCore
static SignonSessionCore * sessionCore(const quint32 id, const QString &method, SignonDaemon *parent)
Definition: signonsessioncore.cpp:108
SignonDaemonNS::StoreOperation::Blob
Definition: signonsessioncoretools.h:51
SignonDaemonNS::SignonSessionCore::setupPlugin
bool setupPlugin()
Definition: signonsessioncore.cpp:153
SignonDaemonNS::CredentialsAccessManager::keysAvailable
bool keysAvailable() const
The CAM manages the encryption keys collection.
Definition: credentialsaccessmanager.cpp:585
SignonDaemonNS::RequestData::m_params
QVariantMap m_params
Definition: signonsessioncoretools.h:85
TRACE
#define TRACE()
Definition: debug.h:28
SignonDaemonNS::SignonSessionCore::loadedPluginMethods
static QStringList loadedPluginMethods(const QString &method)
Definition: signonsessioncore.cpp:210
signonidentity.h
SignonDaemonNS::mergeVariantMaps
QVariantMap mergeVariantMaps(const QVariantMap &map1, const QVariantMap &map2)
Helper method which unites two variant maps.
Definition: signonsessioncoretools.cpp:31
SignonDaemonNS::SignonSessionCore::setId
void setId(quint32 id)
Definition: signonsessioncore.cpp:301
SignonDaemonNS::SignonIdentityInfo
Daemon side representation of identity information.
Definition: signonidentityinfo.h:43
signonauthsession.h
signonui_interface.h
SignonDaemonNS::CredentialsAccessManager::credentialsDB
CredentialsDB * credentialsDB() const
Definition: credentialsaccessmanager.cpp:524
SignonDaemonNS::CredentialsDB
Manages the credentials I/O.
Definition: credentialsdb.h:66
SignonDaemonNS::SignonIdentityInfo::validated
bool validated() const
Definition: signonidentityinfo.h:97
SignonDaemonNS::PluginProxy::cancel
void cancel()
Definition: pluginproxy.cpp:232
accesscontrolmanagerhelper.h
Helper class for access control-related functionality.
SIGNON_UI_DAEMON_OBJECTPATH
#define SIGNON_UI_DAEMON_OBJECTPATH
Definition: signond-common.h:57
SignonDaemonNS::SignonIdentityInfo::setUserName
void setUserName(const QString &userName)
Definition: signonidentityinfo.h:70
SignonDaemonNS::SignonDisposable::setAutoDestruct
void setAutoDestruct(bool value=true) const
Mark the object as used.
Definition: signondisposable.cpp:75
SSO_KEY_USERNAME
#define SSO_KEY_USERNAME
Definition: signonsessioncore.cpp:42
SignonDaemonNS::SignonDisposable::keepInUse
void keepInUse() const
Mark the object as used.
Definition: signondisposable.cpp:57
QMap
Definition: backupifadaptor.h:19
QList
Definition: backupifadaptor.h:18
SignonDaemonNS::SignonSessionCore::cancel
void cancel(const QString &cancelKey)
Definition: signonsessioncore.cpp:254
SignonDaemonNS::SignonIdentityInfo::setValidated
void setValidated(bool validated)
Definition: signonidentityinfo.h:96
SignonDaemonNS::RequestData
Request data.
Definition: signonsessioncoretools.h:71
SignonDaemonNS::SignonSessionCore::SignonSessionCore
SignonSessionCore(quint32 id, const QString &method, int timeout, QObject *parent)
Definition: signonsessioncore.cpp:74