signon  8.57
signonidentity.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  * Copyright (C) 2013 Canonical Ltd.
7  *
8  * Contact: Aurel Popirtac <ext-aurel.popirtac@nokia.com>
9  * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
10  * Contact: Jussi Laako <jussi.laako@linux.intel.com>
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public License
14  * version 2.1 as published by the Free Software Foundation.
15  *
16  * This library is distributed in the hope that it will be useful, but
17  * WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24  * 02110-1301 USA
25  */
26 
27 #include <iostream>
28 #include <QVariantMap>
29 
30 #include "signond-common.h"
31 #include "signonidentity.h"
32 #include "signonui_interface.h"
33 #include "SignOn/uisessiondata.h"
34 #include "SignOn/uisessiondata_priv.h"
35 #include "signoncommon.h"
36 
38 #include "signonidentityadaptor.h"
39 
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."));\
45  return _ret_arg_; \
46  } \
47  } while(0)
48 
49 namespace SignonDaemonNS {
50 
51 const QString internalServerErrName = SIGNOND_INTERNAL_SERVER_ERR_NAME;
52 const QString internalServerErrStr = SIGNOND_INTERNAL_SERVER_ERR_STR;
53 
54 class PendingCallWatcherWithContext: public QDBusPendingCallWatcher
55 {
56  Q_OBJECT
57 
58 public:
59  PendingCallWatcherWithContext(const QDBusPendingCall &call,
60  SignonIdentity *parent):
61  QDBusPendingCallWatcher(call, parent),
62  m_connection(parent->connection()),
63  m_message(parent->message())
64  {
65  }
66 
67  PendingCallWatcherWithContext(const QDBusPendingCall &call,
68  const QDBusConnection &connection,
69  const QDBusMessage &message,
70  SignonIdentity *parent):
71  QDBusPendingCallWatcher(call, parent),
72  m_connection(connection),
73  m_message(message)
74  {
75  }
76 
77  const QDBusConnection &connection() const { return m_connection; }
78  const QDBusMessage &message() const { return m_message; }
79 
80 private:
81  QDBusConnection m_connection;
82  QDBusMessage m_message;
83 };
84 
85 SignonIdentity::SignonIdentity(quint32 id, int timeout,
86  SignonDaemon *parent):
87  SignonDisposable(timeout, parent),
88  m_pInfo(NULL)
89 {
90  m_id = id;
91 
92  (void)new SignonIdentityAdaptor(this);
93 
94  /*
95  * creation of unique name for the given identity
96  * */
97  static quint32 incr = 0;
98  QString objectName = SIGNOND_DAEMON_OBJECTPATH + QLatin1String("/Identity_")
99  + QString::number(incr++, 16);
100  setObjectName(objectName);
101 
102  m_signonui = new SignonUiAdaptor(SIGNON_UI_SERVICE,
104  QDBusConnection::sessionBus(),
105  this);
106 
107  /* Watch for credential updates happening outside of this object (this can
108  * happen on request of authentication plugins) */
109  CredentialsDB *db = CredentialsAccessManager::instance()->credentialsDB();
110  QObject::connect(db, SIGNAL(credentialsUpdated(quint32)),
111  this, SLOT(onCredentialsUpdated(quint32)));
112 }
113 
114 SignonIdentity::~SignonIdentity()
115 {
116  emit unregistered();
117 
118  delete m_signonui;
119  delete m_pInfo;
120 }
121 
123 {
124  return new SignonIdentity(id, parent->identityTimeout(), parent);
125 }
126 
128 {
129  /* Emitting the destroyed signal makes QDBusConnection unregister the
130  * object */
131  Q_EMIT destroyed();
132  deleteLater();
133 }
134 
135 SignonIdentityInfo SignonIdentity::queryInfo(bool &ok, bool queryPassword)
136 {
137  ok = true;
138 
139  bool needLoadFromDB = true;
140  if (m_pInfo) {
141  needLoadFromDB = false;
142  if (queryPassword && m_pInfo->password().isEmpty()) {
143  needLoadFromDB = true;
144  }
145  }
146 
147  if (needLoadFromDB) {
148  if (m_pInfo != 0) {
149  delete m_pInfo;
150  }
151 
152  CredentialsDB *db =
154  m_pInfo = new SignonIdentityInfo(db->credentials(m_id, queryPassword));
155 
156  if (db->lastError().isValid()) {
157  ok = false;
158  delete m_pInfo;
159  m_pInfo = NULL;
160  return SignonIdentityInfo();
161  }
162  }
163 
164  /* Make sure that we clear the password, if the caller doesn't need it */
165  SignonIdentityInfo info = *m_pInfo;
166  if (!queryPassword) {
167  info.setPassword(QString());
168  }
169  return info;
170 }
171 
172 bool SignonIdentity::addReference(const QString &reference)
173 {
174  TRACE() << "addReference: " << reference;
175 
177 
179  if (db == NULL) {
180  BLAME() << "NULL database handler object.";
181  return false;
182  }
183  const QDBusContext &context = static_cast<QDBusContext>(*this);
184  QString appId =
186  context.connection(),
187  context.message());
188  keepInUse();
189  return db->addReference(m_id, appId, reference);
190 }
191 
192 bool SignonIdentity::removeReference(const QString &reference)
193 {
194  TRACE() << "removeReference: " << reference;
195 
197 
199  if (db == NULL) {
200  BLAME() << "NULL database handler object.";
201  return false;
202  }
203  const QDBusContext &context = static_cast<QDBusContext>(*this);
204  QString appId =
206  context.connection(),
207  context.message());
208  keepInUse();
209  return db->removeReference(m_id, appId, reference);
210 }
211 
212 quint32 SignonIdentity::requestCredentialsUpdate(const QString &displayMessage)
213 {
214  SIGNON_RETURN_IF_CAM_UNAVAILABLE(SIGNOND_NEW_IDENTITY);
215 
216  bool ok;
217  SignonIdentityInfo info = queryInfo(ok, false);
218 
219  if (!ok) {
220  BLAME() << "Identity not found.";
221  sendErrorReply(SIGNOND_IDENTITY_NOT_FOUND_ERR_NAME,
222  SIGNOND_IDENTITY_NOT_FOUND_ERR_STR);
223  return SIGNOND_NEW_IDENTITY;
224  }
225  if (!info.storePassword()) {
226  BLAME() << "Password cannot be stored.";
227  sendErrorReply(SIGNOND_STORE_FAILED_ERR_NAME,
228  SIGNOND_STORE_FAILED_ERR_STR);
229  return SIGNOND_NEW_IDENTITY;
230  }
231 
232  //delay dbus reply, ui interaction might take long time to complete
233  setDelayedReply(true);
234 
235  //create ui request to ask password
236  QVariantMap uiRequest;
237  uiRequest.insert(SSOUI_KEY_QUERYPASSWORD, true);
238  uiRequest.insert(SSOUI_KEY_USERNAME, info.userName());
239  uiRequest.insert(SSOUI_KEY_MESSAGE, displayMessage);
240  uiRequest.insert(SSOUI_KEY_CAPTION, info.caption());
241 
242  TRACE() << "Waiting for reply from signon-ui";
243  PendingCallWatcherWithContext *watcher =
244  new PendingCallWatcherWithContext(m_signonui->queryDialog(uiRequest),
245  this);
246  connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
247  this, SLOT(queryUiSlot(QDBusPendingCallWatcher*)));
248 
249  setAutoDestruct(false);
250  return 0;
251 }
252 
254 {
255  TRACE() << "QUERYING INFO";
256 
257  SIGNON_RETURN_IF_CAM_UNAVAILABLE(QVariantMap());
258 
259  bool ok;
260  SignonIdentityInfo info = queryInfo(ok, false);
261 
262  if (!ok) {
263  TRACE();
264  sendErrorReply(SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_NAME,
265  SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_STR +
266  QLatin1String("Database querying error occurred."));
267  return QVariantMap();
268  }
269 
270  if (info.isNew()) {
271  TRACE();
272  sendErrorReply(SIGNOND_IDENTITY_NOT_FOUND_ERR_NAME,
273  SIGNOND_IDENTITY_NOT_FOUND_ERR_STR);
274  return QVariantMap();
275  }
276 
277  keepInUse();
278  info.removeSecrets();
279  return info.toMap();
280 }
281 
282 void SignonIdentity::queryUserPassword(const QVariantMap &params,
283  const QDBusConnection &connection,
284  const QDBusMessage &message)
285 {
286  TRACE() << "Waiting for reply from signon-ui";
287  PendingCallWatcherWithContext *watcher =
288  new PendingCallWatcherWithContext(m_signonui->queryDialog(params),
289  connection, message, this);
290  connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this,
291  SLOT(verifyUiSlot(QDBusPendingCallWatcher*)));
292 
293  setAutoDestruct(false);
294 }
295 
296 bool SignonIdentity::verifyUser(const QVariantMap &params)
297 {
299 
300  bool ok;
301  SignonIdentityInfo info = queryInfo(ok, true);
302 
303  if (!ok) {
304  BLAME() << "Identity not found.";
305  sendErrorReply(SIGNOND_IDENTITY_NOT_FOUND_ERR_NAME,
306  SIGNOND_IDENTITY_NOT_FOUND_ERR_STR);
307  return false;
308  }
309  if (!info.storePassword() || info.password().isEmpty()) {
310  BLAME() << "Password is not stored.";
311  sendErrorReply(SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_NAME,
312  SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_STR);
313  return false;
314  }
315 
316  //delay dbus reply, ui interaction might take long time to complete
317  setDelayedReply(true);
318 
319  //create ui request to ask password
320  QVariantMap uiRequest;
321  uiRequest.unite(params);
322  uiRequest.insert(SSOUI_KEY_QUERYPASSWORD, true);
323  uiRequest.insert(SSOUI_KEY_USERNAME, info.userName());
324  uiRequest.insert(SSOUI_KEY_CAPTION, info.caption());
325 
326  queryUserPassword(uiRequest, connection(), message());
327  return false;
328 }
329 
330 bool SignonIdentity::verifySecret(const QString &secret)
331 {
333 
334  bool ok;
335  queryInfo(ok);
336  if (!ok) {
337  TRACE();
338  sendErrorReply(SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_NAME,
339  SIGNOND_CREDENTIALS_NOT_AVAILABLE_ERR_STR +
340  QLatin1String("Database querying error occurred."));
341  return false;
342  }
343 
345  bool ret = db->checkPassword(m_pInfo->id(), m_pInfo->userName(), secret);
346 
347  keepInUse();
348  return ret;
349 }
350 
352 {
354 
356  if ((db == 0) || !db->removeCredentials(m_id)) {
357  TRACE() << "Error occurred while inserting/updating credentials.";
358  sendErrorReply(SIGNOND_REMOVE_FAILED_ERR_NAME,
359  SIGNOND_REMOVE_FAILED_ERR_STR +
360  QLatin1String("Database error occurred."));
361  return;
362  }
363  setDelayedReply(true);
364  setAutoDestruct(false);
365  PendingCallWatcherWithContext *watcher =
366  new PendingCallWatcherWithContext(m_signonui->removeIdentityData(m_id),
367  this);
368  connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
369  this, SLOT(removeCompleted(QDBusPendingCallWatcher*)));
370  keepInUse();
371 }
372 
373 void SignonIdentity::removeCompleted(QDBusPendingCallWatcher *call)
374 {
375  Q_ASSERT(call != NULL);
376 
377  setAutoDestruct(true);
378  call->deleteLater();
379 
380  PendingCallWatcherWithContext *context =
381  qobject_cast<PendingCallWatcherWithContext*>(call);
382  QDBusPendingReply<> signOnUiReply = *call;
383  bool ok = !signOnUiReply.isError();
384  TRACE() << (ok ? "removeIdentityData succeeded" : "removeIdentityData failed");
385 
386  emit infoUpdated((int)SignOn::IdentityRemoved);
387 
388  QDBusMessage reply = context->message().createReply();
389  context->connection().send(reply);
390 }
391 
393 {
394  TRACE() << "Signout request. Identity ID: " << id();
395  /*
396  * - If the identity is stored (thus registered here)
397  * signal 'sign out' to all identities subsribed to this object,
398  * otherwise the only identity subscribed to this is the newly
399  * created client side identity, which called this method.
400  * - This is just a safety check, as the client identity - if it is a new
401  * one - should not inform server side to sign out.
402  */
403  if (id() != SIGNOND_NEW_IDENTITY) {
404  //clear stored sessiondata
405  CredentialsDB *db =
407  if ((db == 0) || !db->removeData(m_id)) {
408  TRACE() << "clear data failed";
409  }
410 
411  setDelayedReply(true);
412  setAutoDestruct(false);
413  PendingCallWatcherWithContext *watcher =
414  new PendingCallWatcherWithContext(m_signonui->removeIdentityData(m_id),
415  this);
416  connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
417  this, SLOT(signOutCompleted(QDBusPendingCallWatcher*)));
418  }
419  keepInUse();
420  return true;
421 }
422 
423 void SignonIdentity::signOutCompleted(QDBusPendingCallWatcher *call)
424 {
425  Q_ASSERT(call != NULL);
426 
427  setAutoDestruct(true);
428  call->deleteLater();
429 
430  PendingCallWatcherWithContext *context =
431  qobject_cast<PendingCallWatcherWithContext*>(call);
432  QDBusPendingReply<> signOnUiReply = *call;
433  bool ok = !signOnUiReply.isError();
434  TRACE() << (ok ? "removeIdentityData succeeded" : "removeIdentityData failed");
435 
436  emit infoUpdated((int)SignOn::IdentitySignedOut);
437 
438  QDBusMessage reply = context->message().createReply();
439  reply << ok;
440  context->connection().send(reply);
441 }
442 
443 void SignonIdentity::onCredentialsUpdated(quint32 id)
444 {
445  if (id != m_id) return;
446 
447  TRACE() << m_id;
448 
449  /* Clear the cached information about the identity; some of it might not be
450  * valid anymore */
451  if (m_pInfo) {
452  delete m_pInfo;
453  m_pInfo = NULL;
454  }
455 
456  emit infoUpdated((int)SignOn::IdentityDataUpdated);
457 }
458 
459 quint32 SignonIdentity::store(const QVariantMap &info)
460 {
461  keepInUse();
462  SIGNON_RETURN_IF_CAM_UNAVAILABLE(SIGNOND_NEW_IDENTITY);
463 
464  const QDBusContext &context = static_cast<QDBusContext>(*this);
465  QString appId =
467  context.connection(),
468  context.message());
469 
470  const QVariant container = info.value(SIGNOND_IDENTITY_INFO_AUTHMETHODS);
471  MethodMap methods = container.isValid() ?
472  qdbus_cast<MethodMap>(container.value<QDBusArgument>()) : MethodMap();
473 
474  //Add creator to owner list if it has AID
475  QStringList ownerList =
476  info.value(SIGNOND_IDENTITY_INFO_OWNER).toStringList();
477  if (!appId.isNull())
478  ownerList.append(appId);
479 
480  if (m_pInfo == 0) {
481  m_pInfo = new SignonIdentityInfo(info);
482  m_pInfo->setMethods(methods);
483  m_pInfo->setOwnerList(ownerList);
484  } else {
485  if (info.contains(SIGNOND_IDENTITY_INFO_SECRET)) {
486  QString secret = info.value(SIGNOND_IDENTITY_INFO_SECRET).toString();
487  m_pInfo->setPassword(secret);
488  }
489  bool storeSecret =
490  info.value(SIGNOND_IDENTITY_INFO_STORESECRET).toBool();
491  QString userName =
492  info.value(SIGNOND_IDENTITY_INFO_USERNAME).toString();
493  QString caption =
494  info.value(SIGNOND_IDENTITY_INFO_CAPTION).toString();
495  QStringList realms =
496  info.value(SIGNOND_IDENTITY_INFO_REALMS).toStringList();
497  QStringList accessControlList =
498  info.value(SIGNOND_IDENTITY_INFO_ACL).toStringList();
499  int type = info.value(SIGNOND_IDENTITY_INFO_TYPE).toInt();
500 
501  m_pInfo->setStorePassword(storeSecret);
502  m_pInfo->setUserName(userName);
503  m_pInfo->setCaption(caption);
504  m_pInfo->setMethods(methods);
505  m_pInfo->setRealms(realms);
506  m_pInfo->setAccessControlList(accessControlList);
507  m_pInfo->setOwnerList(ownerList);
508  m_pInfo->setType(type);
509  }
510 
511  m_id = storeCredentials(*m_pInfo);
512 
513  if (m_id == SIGNOND_NEW_IDENTITY) {
514  sendErrorReply(SIGNOND_STORE_FAILED_ERR_NAME,
515  SIGNOND_STORE_FAILED_ERR_STR);
516  }
517 
518  return m_id;
519 }
520 
522 {
524  if (db == NULL) {
525  BLAME() << "NULL database handler object.";
526  return SIGNOND_NEW_IDENTITY;
527  }
528 
529  bool newIdentity = info.isNew();
530 
531  if (newIdentity)
532  m_id = db->insertCredentials(info);
533  else
534  db->updateCredentials(info);
535 
536  if (db->errorOccurred()) {
537  if (newIdentity)
538  m_id = SIGNOND_NEW_IDENTITY;
539 
540  TRACE() << "Error occurred while inserting/updating credentials.";
541  } else {
542  if (m_pInfo) {
543  delete m_pInfo;
544  m_pInfo = NULL;
545  }
546  Q_EMIT stored(this);
547 
548  TRACE() << "FRESH, JUST STORED CREDENTIALS ID:" << m_id;
549  emit infoUpdated((int)SignOn::IdentityDataUpdated);
550  }
551  return m_id;
552 }
553 
554 void SignonIdentity::queryUiSlot(QDBusPendingCallWatcher *call)
555 {
556  TRACE();
557  Q_ASSERT(call != NULL);
558 
559  setAutoDestruct(true);
560 
561  PendingCallWatcherWithContext *context =
562  qobject_cast<PendingCallWatcherWithContext*>(call);
563  const QDBusMessage &message = context->message();
564  const QDBusConnection &connection = context->connection();
565 
566  QDBusMessage errReply;
567  QDBusPendingReply<QVariantMap> reply = *call;
568  call->deleteLater();
569 
570  QVariantMap resultParameters;
571  if (!reply.isError() && reply.count()) {
572  resultParameters = reply.argumentAt<0>();
573  } else {
574  errReply = message.createErrorReply(
575  SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME,
576  SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR);
577  connection.send(errReply);
578  return;
579  }
580 
581  if (!resultParameters.contains(SSOUI_KEY_ERROR)) {
582  //no reply code
583  errReply = message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
584  SIGNOND_INTERNAL_SERVER_ERR_STR);
585  connection.send(errReply);
586  return;
587  }
588 
589  int errorCode = resultParameters.value(SSOUI_KEY_ERROR).toInt();
590  TRACE() << "error: " << errorCode;
591  if (errorCode != QUERY_ERROR_NONE) {
592  if (errorCode == QUERY_ERROR_CANCELED)
593  errReply =
594  message.createErrorReply(
595  SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME,
596  SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR);
597  else
598  errReply =
599  message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
600  QString(QLatin1String("signon-ui call returned error %1")).
601  arg(errorCode));
602 
603  connection.send(errReply);
604  return;
605  }
606 
607  if (resultParameters.contains(SSOUI_KEY_PASSWORD)) {
608  CredentialsDB *db =
610  if (db == NULL) {
611  BLAME() << "NULL database handler object.";
612  errReply = message.createErrorReply(SIGNOND_STORE_FAILED_ERR_NAME,
613  SIGNOND_STORE_FAILED_ERR_STR);
614  connection.send(errReply);
615  return;
616  }
617 
618  //store new password
619  if (m_pInfo) {
620  m_pInfo->setPassword(resultParameters[SSOUI_KEY_PASSWORD].toString());
621 
622  quint32 ret = db->updateCredentials(*m_pInfo);
623  delete m_pInfo;
624  m_pInfo = NULL;
625  if (ret != SIGNOND_NEW_IDENTITY) {
626  QDBusMessage dbusreply = message.createReply();
627  dbusreply << quint32(m_id);
628  connection.send(dbusreply);
629  return;
630  } else{
631  BLAME() << "Error during update";
632  }
633  }
634  }
635 
636  //this should not happen, return error
637  errReply = message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
638  SIGNOND_INTERNAL_SERVER_ERR_STR);
639  connection.send(errReply);
640  return;
641 }
642 
643 void SignonIdentity::verifyUiSlot(QDBusPendingCallWatcher *call)
644 {
645  TRACE();
646  Q_ASSERT(call != NULL);
647 
648  setAutoDestruct(true);
649 
650  PendingCallWatcherWithContext *context =
651  qobject_cast<PendingCallWatcherWithContext*>(call);
652  const QDBusMessage &message = context->message();
653  const QDBusConnection &connection = context->connection();
654 
655  QDBusMessage errReply;
656  QDBusPendingReply<QVariantMap> reply = *call;
657  call->deleteLater();
658  QVariantMap resultParameters;
659  if (!reply.isError() && reply.count()) {
660  resultParameters = reply.argumentAt<0>();
661  } else {
662  errReply =
663  message.createErrorReply(
664  SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME,
665  SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR);
666  connection.send(errReply);
667  return;
668  }
669 
670  if (!resultParameters.contains(SSOUI_KEY_ERROR)) {
671  //no reply code
672  errReply = message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
673  SIGNOND_INTERNAL_SERVER_ERR_STR);
674  connection.send(errReply);
675  return;
676  }
677 
678  int errorCode = resultParameters.value(SSOUI_KEY_ERROR).toInt();
679  TRACE() << "error: " << errorCode;
680  if (errorCode != QUERY_ERROR_NONE) {
681  if (errorCode == QUERY_ERROR_CANCELED)
682  errReply = message.createErrorReply(
683  SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_NAME,
684  SIGNOND_IDENTITY_OPERATION_CANCELED_ERR_STR);
685  else if (errorCode == QUERY_ERROR_FORGOT_PASSWORD)
686  errReply = message.createErrorReply(
687  SIGNOND_FORGOT_PASSWORD_ERR_NAME,
688  SIGNOND_FORGOT_PASSWORD_ERR_STR);
689  else
690  errReply = message.createErrorReply(
691  SIGNOND_INTERNAL_SERVER_ERR_NAME,
692  QString(QLatin1String("signon-ui call "
693  "returned error %1")).
694  arg(errorCode));
695 
696  connection.send(errReply);
697  return;
698  }
699 
700  if (resultParameters.contains(SSOUI_KEY_PASSWORD)) {
701  CredentialsDB *db =
703  if (db == NULL) {
704  BLAME() << "NULL database handler object.";
705  errReply = message.createErrorReply(SIGNOND_STORE_FAILED_ERR_NAME,
706  SIGNOND_STORE_FAILED_ERR_STR);
707  connection.send(errReply);
708  return;
709  }
710 
711  //compare passwords
712  if (m_pInfo) {
713  bool ret =
714  m_pInfo->password() == resultParameters[SSOUI_KEY_PASSWORD].
715  toString();
716 
717  if (!ret && resultParameters.contains(SSOUI_KEY_CONFIRMCOUNT)) {
718  int count = resultParameters[SSOUI_KEY_CONFIRMCOUNT].toInt();
719  TRACE() << "retry count:" << count;
720  if (count > 0) { //retry
721  resultParameters[SSOUI_KEY_CONFIRMCOUNT] = (count-1);
722  resultParameters[SSOUI_KEY_MESSAGEID] =
723  QUERY_MESSAGE_NOT_AUTHORIZED;
724  queryUserPassword(resultParameters, connection, message);
725  return;
726  } else {
727  //TODO show error note here if needed
728  }
729  }
730  delete m_pInfo;
731  m_pInfo = NULL;
732  QDBusMessage dbusreply = message.createReply();
733  dbusreply << ret;
734  connection.send(dbusreply);
735  return;
736  }
737  }
738  //this should not happen, return error
739  errReply = message.createErrorReply(SIGNOND_INTERNAL_SERVER_ERR_NAME,
740  SIGNOND_INTERNAL_SERVER_ERR_STR);
741  connection.send(errReply);
742  return;
743 }
744 
745 } //namespace SignonDaemonNS
746 
747 #include "signonidentity.moc"
bool removeData(const quint32 id, const QString &method=QString())
const QString internalServerErrName
#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)
#define BLAME()
Definition: debug.h:32
static AccessControlManagerHelper * instance()
bool addReference(const QString &reference)
void destroy()
Performs any predestruction operations and the destruction itself.
void verifyUiSlot(QDBusPendingCallWatcher *call)
quint32 insertCredentials(const SignonIdentityInfo &info)
quint32 updateCredentials(const SignonIdentityInfo &info)
SignOn::CredentialsDBError lastError() const
bool verifySecret(const QString &secret)
bool addReference(const quint32 id, const QString &token, const QString &reference)
bool verifyUser(const QVariantMap &params)
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)
bool removeReference(const quint32 id, const QString &token, const QString &reference=QString())
const QString internalServerErrStr
QMap< MethodName, MechanismsList > MethodMap
quint32 store(const QVariantMap &info)
#define TRACE()
Definition: debug.h:28
bool removeReference(const QString &reference)
Daemon side representation of identity.
Daemon side representation of identity information.
bool checkPassword(const quint32 id, const QString &username, const QString &password)
Manages the credentials I/O.
Definition: credentialsdb.h:66
Helper class for access control-related functionality.
#define SIGNON_UI_DAEMON_OBJECTPATH
quint32 storeCredentials(const SignonIdentityInfo &info)
SignonIdentityInfo queryInfo(bool &ok, bool queryPassword=true)
const QVariantMap toMap() const
int identityTimeout() const
Returns the number of seconds of inactivity after which identity objects might be automatically delet...