//--------------------------------------------------------------------- LockboxAccessResultPtr LockboxAccessResult::create( ElementPtr rootEl, IMessageSourcePtr messageSource ) { LockboxAccessResultPtr ret(new LockboxAccessResult); IMessageHelper::fill(*ret, rootEl, messageSource); ret->mLockboxInfo = MessageHelper::createLockbox(rootEl->findFirstChildElement("lockbox")); ret->mNamespaceGrantChallengeInfo = MessageHelper::createNamespaceGrantChallenge(rootEl->findFirstChildElement("namespaceGrantChallenge")); ElementPtr identitiesEl = rootEl->findFirstChildElement("identities"); if (identitiesEl) { ElementPtr identityEl = identitiesEl->findFirstChildElement("identity"); while (identityEl) { IdentityInfo info = MessageHelper::createIdentity(identityEl); if (info.hasData()) { ret->mIdentities.push_back(info); } identityEl = identityEl->findNextSiblingElement("identity"); } } return ret; }
//--------------------------------------------------------------------- DocumentPtr IdentityAccessRolodexCredentialsGetRequest::encode() { DocumentPtr ret = IMessageHelper::createDocumentWithRoot(*this); ElementPtr root = ret->getFirstChildElement(); String clientNonce = IHelper::randomString(32); IdentityInfo identityInfo; identityInfo.mURI = mIdentityInfo.mURI; identityInfo.mProvider = mIdentityInfo.mProvider; identityInfo.mAccessToken = mIdentityInfo.mAccessToken; if (mIdentityInfo.mAccessSecret.hasData()) { identityInfo.mAccessSecretProofExpires = zsLib::now() + Seconds(OPENPEER_STACK_MESSAGE_IDENTITY_ACCESS_LOCKBOX_UPDATE_EXPIRES_TIME_IN_SECONDS); identityInfo.mAccessSecretProof = IHelper::convertToHex(*IHelper::hmac(*IHelper::hmacKeyFromPassphrase(mIdentityInfo.mAccessSecret), "identity-access-validate:" + identityInfo.mURI + ":" + clientNonce + ":" + IHelper::timeToString(identityInfo.mAccessSecretProofExpires) + ":" + identityInfo.mAccessToken + ":rolodex-credentials-get")); } root->adoptAsLastChild(IMessageHelper::createElementWithText("nonce", clientNonce)); if (identityInfo.hasData()) { root->adoptAsLastChild(MessageHelper::createElement(identityInfo)); } return ret; }
//--------------------------------------------------------------------- DocumentPtr RolodexAccessRequest::encode() { DocumentPtr ret = IMessageHelper::createDocumentWithRoot(*this); ElementPtr rootEl = ret->getFirstChildElement(); String clientNonce = IHelper::randomString(32); IdentityInfo identityInfo; identityInfo.mURI = mIdentityInfo.mURI; identityInfo.mProvider = mIdentityInfo.mProvider; identityInfo.mAccessToken = mIdentityInfo.mAccessToken; if (mIdentityInfo.mAccessSecret.hasData()) { identityInfo.mAccessSecretProofExpires = zsLib::now() + Seconds(OPENPEER_STACK_MESSAGE_ROLODEX_ACCESS_REQUEST_EXPIRES_TIME_IN_SECONDS); identityInfo.mAccessSecretProof = IHelper::convertToHex(*IHelper::hmac(*IHelper::hmacKeyFromPassphrase(mIdentityInfo.mAccessSecret), "identity-access-validate:" + identityInfo.mURI + ":" + clientNonce + ":" + IHelper::timeToString(identityInfo.mAccessSecretProofExpires) + ":" + identityInfo.mAccessToken + ":lockbox-access")); } rootEl->adoptAsLastChild(IMessageHelper::createElementWithText("nonce", clientNonce)); if (identityInfo.hasData()) { rootEl->adoptAsLastChild(MessageHelper::createElement(identityInfo)); } RolodexInfo rolodexInfo; rolodexInfo.mServerToken = mRolodexInfo.mServerToken; rolodexInfo.mVersion = mRolodexInfo.mVersion; rolodexInfo.mRefreshFlag = mRolodexInfo.mRefreshFlag; if (rolodexInfo.hasData()) { rootEl->adoptAsLastChild(MessageHelper::createElement(rolodexInfo)); } AgentInfo agentInfo; agentInfo = UseStack::agentInfo(); agentInfo.mergeFrom(mAgentInfo, true); if (mAgentInfo.hasData()) { rootEl->adoptAsLastChild(MessageHelper::createElement(agentInfo)); } if (mGrantID.hasData()) { rootEl->adoptAsLastChild(IMessageHelper::createElementWithID("grant", mGrantID)); } return ret; }
//--------------------------------------------------------------------- LockboxIdentitiesUpdateResultPtr LockboxIdentitiesUpdateResult::create( ElementPtr root, IMessageSourcePtr messageSource ) { LockboxIdentitiesUpdateResultPtr ret(new LockboxIdentitiesUpdateResult); IMessageHelper::fill(*ret, root, messageSource); ElementPtr identitiesEl = root->findFirstChildElement("identities"); if (identitiesEl) { ElementPtr identityEl = identitiesEl->findFirstChildElement("identity"); while (identityEl) { IdentityInfo info = MessageHelper::createIdentity(identityEl); if (info.hasData()) { ret->mIdentities.push_back(info); } identityEl = identityEl->findNextSiblingElement("identity"); } } return ret; }
//--------------------------------------------------------------------- RolodexContactsGetResultPtr RolodexContactsGetResult::create( ElementPtr rootEl, IMessageSourcePtr messageSource ) { RolodexContactsGetResultPtr ret(new RolodexContactsGetResult); IMessageHelper::fill(*ret, rootEl, messageSource); ElementPtr identitiesEl = rootEl->findFirstChildElement("identities"); if (identitiesEl) { ElementPtr identityEl = identitiesEl->findFirstChildElement("identity"); while (identityEl) { IdentityInfo info = MessageHelper::createIdentity(identityEl); if (info.hasData()) { #define OPENPEER_STACK_MESSAGE_ROLODEX_IMPROPER_FACEBOOK_URL "identity://facebook/" #define OPENPEER_STACK_MESSAGE_ROLODEX_ROPER_FACEBOOK_URL "identity://facebook.com/" #define HORRIBLE_HACK_TO_PREVENT_INVALID_FORMED_FACEBOOK_URIS 1 if (info.mURI.hasData()) { if (0 == info.mURI.compare(0, strlen(OPENPEER_STACK_MESSAGE_ROLODEX_IMPROPER_FACEBOOK_URL), OPENPEER_STACK_MESSAGE_ROLODEX_IMPROPER_FACEBOOK_URL)) { ZS_LOG_WARNING(Detail, String("RolodexContactsGetResult [") + ret->mID + "] Fixed imporer facebook identity URI. Please contact rolodex admin to repair rolodex service. URI=" + info.mURI) info.mURI = OPENPEER_STACK_MESSAGE_ROLODEX_ROPER_FACEBOOK_URL + info.mURI.substr(strlen(OPENPEER_STACK_MESSAGE_ROLODEX_IMPROPER_FACEBOOK_URL)); } } #define HORRIBLE_HACK_TO_PREVENT_INVALID_FORMED_FACEBOOK_URIS 2 ret->mIdentities.push_back(info); } identityEl = identityEl->findNextSiblingElement("identity"); } } ret->mRolodexInfo = MessageHelper::createRolodex(rootEl->findFirstChildElement("rolodex")); return ret; }
void TimeoutsTest::identityTimeout() { QEventLoop loop; QTimer::singleShot(test_timeout, &loop, SLOT(quit())); QObject::connect(this, SIGNAL(finished()), &loop, SLOT(quit())); QMap<MethodName,MechanismsList> methods; methods.insert("dummy", QStringList() << "mech1" << "mech2"); IdentityInfo info = IdentityInfo(QLatin1String("timeout test"), QLatin1String("timeout@test"), methods); info.setAccessControlList(QStringList() << "*"); Identity *identity = Identity::newIdentity(info); QVERIFY(identity != NULL); QObject::connect(identity, SIGNAL(credentialsStored(const quint32)), this, SLOT(credentialsStored(const quint32))); QObject::connect(identity, SIGNAL(error(const SignOn::Error&)), this, SLOT(identityError(const SignOn::Error&))); identity->storeCredentials(); loop.exec(); QVERIFY(identity->id() != SSO_NEW_IDENTITY); QDBusConnection conn = SIGNOND_BUS; QDBusMessage msg = QDBusMessage::createMethodCall(SIGNOND_SERVICE, SIGNOND_DAEMON_OBJECTPATH, SIGNOND_DAEMON_INTERFACE, "getIdentity"); QList<QVariant> args; args << identity->id(); msg.setArguments(args); QDBusMessage reply = conn.call(msg); QCOMPARE(reply.type(), QDBusMessage::ReplyMessage); QDBusObjectPath objectPath = reply.arguments()[0].value<QDBusObjectPath>(); QString path = objectPath.path(); qDebug() << "Got path" << path; QVERIFY(!path.isEmpty()); bool success; QTest::qSleep(100); success = triggerDisposableCleanup(); QVERIFY(success); /* The identity object must exist now */ QVERIFY(identityAlive(path)); QTest::qSleep(6 * 1000); success = triggerDisposableCleanup(); QVERIFY(success); /* After SSO_IDENTITY_TIMEOUT seconds, the identity must have been * destroyed */ QVERIFY(!identityAlive(path)); /* Calling a method on the client should re-register the identity */ QSignalSpy removed(identity, SIGNAL(removed())); QObject::connect(identity, SIGNAL(removed()), &loop, SLOT(quit()), Qt::QueuedConnection); identity->remove(); loop.exec(); QCOMPARE(removed.count(), 1); }
void TimeoutsTest::identityRegisterTwice() { QEventLoop loop; QTimer::singleShot(test_timeout, &loop, SLOT(quit())); QObject::connect(this, SIGNAL(finished()), &loop, SLOT(quit())); QMap<MethodName,MechanismsList> methods; methods.insert("dummy", QStringList() << "mech1" << "mech2"); IdentityInfo info = IdentityInfo(QLatin1String("timeout test"), QLatin1String("timeout@test"), methods); info.setAccessControlList(QStringList() << "*"); Identity *identity = Identity::newIdentity(info); QVERIFY(identity != NULL); QObject::connect(identity, SIGNAL(credentialsStored(const quint32)), this, SLOT(credentialsStored(const quint32))); QObject::connect(identity, SIGNAL(error(const SignOn::Error &)), this, SLOT(identityError(const SignOn::Error &))); identity->storeCredentials(); loop.exec(); QVERIFY(identity->id() != SSO_NEW_IDENTITY); QDBusConnection conn = SIGNOND_BUS; QDBusMessage msg = QDBusMessage::createMethodCall(SIGNOND_SERVICE, SIGNOND_DAEMON_OBJECTPATH, SIGNOND_DAEMON_INTERFACE, "getIdentity"); QList<QVariant> args; args << identity->id(); msg.setArguments(args); QDBusMessage reply = conn.call(msg); QCOMPARE(reply.type(), QDBusMessage::ReplyMessage); QDBusObjectPath objectPath = reply.arguments()[0].value<QDBusObjectPath>(); QString path = objectPath.path(); qDebug() << "Got path" << path; QVERIFY(!path.isEmpty()); bool success; QTest::qSleep(100); success = triggerDisposableCleanup(); QVERIFY(success); /* The identity object must exist now */ QVERIFY(identityAlive(path)); QTest::qSleep(6 * 1000); /* now we register the same identity again. The expected behavior is that * the registration succeeds, possibly returning the same object path as * before. * This is to test a regression (NB#182914) which was happening because * signond was deleting the expired Identity immediately after returning * its object path to the client. */ reply = conn.call(msg); QVERIFY(reply.type() == QDBusMessage::ReplyMessage); objectPath = reply.arguments()[0].value<QDBusObjectPath>(); path = objectPath.path(); qDebug() << "Got path" << path; QVERIFY(!path.isEmpty()); QVERIFY(identityAlive(path)); }
//--------------------------------------------------------------------- DocumentPtr LockboxIdentitiesUpdateRequest::encode() { DocumentPtr ret = IMessageHelper::createDocumentWithRoot(*this); ElementPtr root = ret->getFirstChildElement(); String clientNonce = IHelper::randomString(32); LockboxInfo lockboxInfo; lockboxInfo.mAccessToken = mLockboxInfo.mAccessToken; if (mLockboxInfo.mAccessSecret.hasData()) { lockboxInfo.mAccessSecretProofExpires = zsLib::now() + Seconds(OPENPEER_STACK_MESSAGE_LOCKBOX_IDENTITIES_UPDATE_REQUEST_EXPIRES_TIME_IN_SECONDS); lockboxInfo.mAccessSecretProof = IHelper::convertToHex(*IHelper::hmac(*IHelper::hmacKeyFromPassphrase(mLockboxInfo.mAccessSecret), "lockbox-access-validate:" + clientNonce + ":" + IHelper::timeToString(lockboxInfo.mAccessSecretProofExpires) + ":" + lockboxInfo.mAccessToken + ":lockbox-identities-update")); } IdentityInfoList identities; for (IdentityInfoList::iterator iter = mIdentitiesToUpdate.begin(); iter != mIdentitiesToUpdate.end(); ++iter) { IdentityInfo &listIdentity = (*iter); IdentityInfo identityInfo; identityInfo.mURI = listIdentity.mURI; identityInfo.mProvider = listIdentity.mProvider; identityInfo.mAccessToken = listIdentity.mAccessToken; if (listIdentity.mAccessSecret.hasData()) { identityInfo.mAccessSecretProofExpires = zsLib::now() + Seconds(OPENPEER_STACK_MESSAGE_LOCKBOX_IDENTITIES_UPDATE_REQUEST_EXPIRES_TIME_IN_SECONDS); identityInfo.mAccessSecretProof = IHelper::convertToHex(*IHelper::hmac(*IHelper::hmacKeyFromPassphrase(listIdentity.mAccessSecret), "identity-access-validate:" + identityInfo.mURI + ":" + clientNonce + ":" + IHelper::timeToString(identityInfo.mAccessSecretProofExpires) + ":" + identityInfo.mAccessToken + ":lockbox-access-update")); } if (identityInfo.hasData()) { identityInfo.mDisposition = IdentityInfo::Disposition_Update; identities.push_back(identityInfo); } } for (IdentityInfoList::iterator iter = mIdentitiesToRemove.begin(); iter != mIdentitiesToRemove.end(); ++iter) { IdentityInfo &listIdentity = (*iter); IdentityInfo identityInfo; identityInfo.mURI = listIdentity.mURI; identityInfo.mProvider = listIdentity.mProvider; if (identityInfo.hasData()) { identityInfo.mDisposition = IdentityInfo::Disposition_Remove; identities.push_back(identityInfo); } } root->adoptAsLastChild(IMessageHelper::createElementWithText("nonce", clientNonce)); if (lockboxInfo.hasData()) { root->adoptAsLastChild(MessageHelper::createElement(lockboxInfo)); } ElementPtr identitiesEl = IMessageHelper::createElement("identities"); for (IdentityInfoList::iterator iter = identities.begin(); iter != identities.end(); ++iter) { IdentityInfo &listIdentity = (*iter); identitiesEl->adoptAsLastChild(MessageHelper::createElement(listIdentity)); } if (identitiesEl->hasChildren()) { root->adoptAsLastChild(identitiesEl); } return ret; }