diff -r 000000000000 -r 62f9d29f7211 webservices/idwsfplugin/src/senidwsfplugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webservices/idwsfplugin/src/senidwsfplugin.cpp Thu Jan 07 16:19:19 2010 +0200 @@ -0,0 +1,1458 @@ +/* +* Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + + + + + + +// INCLUDE FILES +#include + +#include // error codes and framework ids +#include +#include + +#include "msencoreservicemanager.h" +#include "msentransport.h" +#include "sendebug.h" +#include "senlogger.h" + +#include "senidwsfplugin.h" +#include "idwsfdiscoveryserviceclient.h" +#include "idwsfservicesession.h" +#include "idwsfcoreserviceconsumer.h" +#include "midwsfsessionvalidator.h" + +#include +#include + + +// Create instance of concrete ECOM interface implementation +CSenIdWsfPlugin* CSenIdWsfPlugin::NewL(TAny* aManager) + { + MSenCoreServiceManager* manager = + reinterpret_cast(aManager); + + CSenIdWsfPlugin* self = new (ELeave) CSenIdWsfPlugin(*manager); + CleanupStack::PushL (self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +// Implementation of CSIF + +// Constructor +CSenIdWsfPlugin::CSenIdWsfPlugin(MSenCoreServiceManager& aManager) +: iManager(aManager) + { + } + +CSenIdWsfPlugin::~CSenIdWsfPlugin() + { + //CSenIdWsfPlugin::Log()->Write(_L8("CSenIdWsfPlugin::~CSenIdWsfPlugin()")); + } + +// Second phase construction. +void CSenIdWsfPlugin::ConstructL() + { + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenIdWsfPlugin::ConstructL - Version 2 [2006-05-09]"); + + // Results to add a DUPLICATE xmlns in parse! + BaseConstructL(KIdWsfFrameworkXMLNS, KIdWsfFrameworkLocalname); + } + +// New methods + +/* +RFileLogger* CSenIdWsfPlugin::Log() const + { + return iManager.Log(); + }*/ + +////////////////////////////////////////////////////////////////////////// + + +// Implementation of CSIF + +/** +* Return a system wide unique string to identify this framework +* +* @return TDesC8 that uniquely identifies this framework. +*/ +const TDesC8& CSenIdWsfPlugin::Id() + { + return KDefaultIdWsfFrameworkID(); + } + +TInt CSenIdWsfPlugin::CompareSDScore(const TSDScore& aSDScoreLeft, + const TSDScore& aSDScoreRight) + { + //"greater" means better matchScore, i.e. further down in a list! + return (aSDScoreLeft.iScore - aSDScoreRight.iScore); + } + +/** +* Try to find one or more services that match the given ServiceDescription. +* Register ServiceDescriptions for these to the owner of the framework, +* i.e. to the ServiceManager. Return the number of ServiceDescriptions that +* were added. +* +* @param aPattern - A ServiceDescriptin that should be treated as a pattern +* @param aRemoteConsumer - the consumer sending the request +* @param aErrorMsg - in case that return value is negative, this may contain +* error as descriptor (SOAP Fault etc) +* +* return (TInt) aCount of matching ServiceDescriptions that were added +*/ +TInt CSenIdWsfPlugin::AddServiceDescriptionL( MSenServiceDescription& aPattern, + MSenRemoteServiceConsumer& aRemoteConsumer, + HBufC8*& /* aErrorMsg */ ) + { + CSLOG(aRemoteConsumer.ConnectionId() , KMinLogLevel,(_L("Entered CSenIdWsfPlugin::AddServiceDescriptionL"))); + + if( aPattern.Contract().Length() == 0 + || ( aPattern.FrameworkId() != KDefaultIdWsfFrameworkID && + aPattern.FrameworkId() != KNullDesC8 ) ) + { + return 0; + } + + +#ifdef _SENDEBUG + HBufC8* pAsXml = aPattern.AsXmlL(); + if(pAsXml) + { + CleanupStack::PushL(pAsXml); + CSLOG_ALL(aRemoteConsumer.ConnectionId() , KMaxLogLevel,(*pAsXml)); + CleanupStack::PopAndDestroy(); // pAsXml + } +#endif + + RArray searchResults; + RPointerArray serviceDescriptions; + RPointerArray tempArray; + + CleanupClosePushL(searchResults); + CleanupClosePushL(serviceDescriptions); + CleanupClosePushL(tempArray); + + TLinearOrder order(&CSenIdWsfPlugin::CompareSDScore); + + TInt retVal = + Manager().ServiceDescriptionsL(serviceDescriptions, + KIdWsfFrameworkDiscoveryServiceContract); + + if(retVal != KErrNone) + { + CleanupStack::PopAndDestroy(3); // close the RPointerArrays + return 0; // zero SD's were added + } + + CIdWsfDiscoveryServiceClient* pDSClient = NULL; + CSenIdentityProvider* pIdentityProvider = IdentityProviderL(&aPattern); + + ////////////////////////////////////////////////////////////////////////// + + if(!pIdentityProvider) + { + CleanupStack::PopAndDestroy(3); // close the RPointerArrays + return 0;//no possibility to add any SD as long as NO IdP is available! + } + ////////////////////////////////////////////////////////////////////////// + + TInt attempts = 0; + + RPointerArray invalidDSClients; + CleanupClosePushL(invalidDSClients); + MSenServiceDescription *pDSDescription = NULL; + + TInt i = 0; + while((i < serviceDescriptions.Count()) && (searchResults.Count() < 1)) + { + pDSDescription = (MSenServiceDescription*) serviceDescriptions[i]; + if(pDSDescription->DescriptionClassType() == + MSenServiceDescription::EIdWsfDiscoveryServiceClient) + { + pDSClient = (CIdWsfDiscoveryServiceClient*) pDSDescription; + if(pDSClient->IsReadyL()) + { + if( (!pIdentityProvider && + (pDSClient->TrustAnchor() == KNullDesC8())) || + (pIdentityProvider && + (pDSClient->TrustAnchor() == + pIdentityProvider->ProviderID()) )) + { + pDSClient->FindServiceL(tempArray, + aPattern, + aRemoteConsumer); + attempts++; + for(TInt j = 0; j < tempArray.Count(); j++) + { + TSDScore temp; + temp.iSD = tempArray[j]; + temp.iScore = tempArray[j]->ScoreMatchL(aPattern); + searchResults.Append(temp); + //searchResults.Append(tempArray[j]); + } + tempArray.Reset(); + searchResults.Sort(order); + } + else + { + invalidDSClients.Append( + (CSenWSDescription*)pDSDescription); + } + } + else + { + invalidDSClients.Append( + (CSenWSDescription*)pDSDescription); + } + } + else + { + invalidDSClients.Append( + (CSenWSDescription*)pDSDescription); + } + i++; + } + + if(searchResults.Count() < 1) + { + if(attempts < 1) // no DS trusted by the IDP + //that was in the database (senidentities.xml) + { + // get a DS with the IdP as trust anchor + pDSClient = DSClientL(pIdentityProvider, aRemoteConsumer); + if(pDSClient && pDSClient->IsReadyL()) + { + pDSClient->FindServiceL(tempArray, + aPattern, + aRemoteConsumer); + for(TInt j = 0; j < tempArray.Count(); j++) + { + TSDScore temp; + temp.iSD = tempArray[j]; + temp.iScore = tempArray[j]->ScoreMatchL(aPattern); + searchResults.Append(temp); + //searchResults.Append(tempArray[j]); + } + tempArray.Reset(); + searchResults.Sort(order); + } + } + } + + if(searchResults.Count() < 1) + { + // try to validate invalid DS descriptions (clients) + i = 0; + while((i < invalidDSClients.Count()) && (searchResults.Count() < 1)) + { + pDSDescription = (MSenServiceDescription*) invalidDSClients[i]; + if(pDSDescription->DescriptionClassType() == + MSenServiceDescription::EIdWsfDiscoveryServiceClient) + { + pDSClient = (CIdWsfDiscoveryServiceClient*) pDSDescription; + if(ValidateDSL(pDSClient,pIdentityProvider, aRemoteConsumer)) + { + retVal = pDSClient->FindServiceL(tempArray, + aPattern, + aRemoteConsumer); + CSLOG_FORMAT((aRemoteConsumer.ConnectionId() , KNormalLogLevel, _L8("DS client FindServiceL() returned: (%d)"), + retVal)); + retVal = 0; + + for(TInt j = 0; j < tempArray.Count(); j++) + { + TSDScore temp; + temp.iSD = tempArray[j]; + temp.iScore = tempArray[j]->ScoreMatchL(aPattern); + searchResults.Append(temp); + //searchResults.Append(tempArray[j]); + } + searchResults.Sort(order); + } + } + i++; + } + } + + for(i=0; i0 && + (contract == KIdWsfFrameworkDiscoveryServiceContract)) + { + retval = RegisterDSClientL(&aServiceDescription); + } + else + { + if(aServiceDescription.DescriptionClassType() == + MSenServiceDescription::EIdWSFServiceSession) + { + pSession = (CIdWsfServiceSession*) &aServiceDescription; + + retval = Manager().AddServiceDescriptionL(pSession); + } + else + { + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,(_L8("Creating session from description..."))); +#ifdef _SENDEBUG + TPtrC8 con = aServiceDescription.Contract(); + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,_L8(" Using Contract: '%S'"), &con)); +#endif + + pSession = CIdWsfServiceSession::NewLC(*this); + retval = pSession->InitializeFromL(aServiceDescription); + if (retval == KErrNone) + { + retval = Manager().AddServiceDescriptionL(pSession); + CleanupStack::Pop(pSession); + } + else + { + CleanupStack::PopAndDestroy(pSession); + } + } + } + + return retval; + } + +TInt CSenIdWsfPlugin::UnregisterServiceDescriptionL( + MSenServiceDescription& aServiceDescription) + { + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,(_L8("UnRegisterServiceDescriptionL(.)"))); + + +#ifdef _SENDEBUG + HBufC8* pAsXml = aServiceDescription.AsXmlL(); + if(pAsXml) + { + CleanupStack::PushL(pAsXml); + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMaxLogLevel ,(*pAsXml)); + CleanupStack::PopAndDestroy(); // ptr + } +#endif // _SENDEBUG + + + TInt retval = KErrNone; + CIdWsfServiceSession *pSession = NULL; + TPtrC8 contract = aServiceDescription.Contract(); + + if(contract == KIdWsfFrameworkAuthenticationServiceContract) + { + retval = UnRegisterASClientL(&aServiceDescription); + } + else if(contract.Length()>0 && + (contract == KIdWsfFrameworkDiscoveryServiceContract)) + { + retval = UnRegisterDSClientL(&aServiceDescription); + } + else + { + if(aServiceDescription.DescriptionClassType() == + MSenServiceDescription::EIdWSFServiceSession) + { + pSession = (CIdWsfServiceSession*) &aServiceDescription; + retval = Manager().RemoveServiceDescriptionL(*pSession); + } + else + { +#ifdef _SENDEBUG + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"Creating session from description..."); + TPtrC8 con = aServiceDescription.Contract(); + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,_L8("-contract: '%S'"), &con)); +#endif // _SENDEBUG + + pSession = CIdWsfServiceSession::NewLC(*this); + retval = pSession->InitializeFromL(aServiceDescription); + if (retval == KErrNone) + { + retval = Manager().RemoveServiceDescriptionL(*pSession); + } + CleanupStack::PopAndDestroy(pSession); + } + } + + return retval; + } + +TInt CSenIdWsfPlugin::UnRegisterASClientL( + MSenServiceDescription *aServiceDescription) + { +#ifdef _SENDEBUG + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenIdWsfPlugin::UnRegisterASClientL"); + TPtrC8 endpoint = aServiceDescription->Endpoint(); + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,(endpoint)); +#endif + + TInt retval = KErrNone; + + CIdWsfServiceSession *pSession = NULL; + CIdWsfAuthenticationServiceClient *pASClient = NULL; + + if(aServiceDescription->DescriptionClassType() == + MSenServiceDescription::EIdWsfAuthenticationServiceClient) + { + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,(_L8("This ServiceDescription is already an AS Client"))); + pASClient = (CIdWsfAuthenticationServiceClient*)aServiceDescription; + + retval = Manager().RemoveServiceDescriptionL(*pASClient); + } + else + { + pSession = CIdWsfServiceSession::NewLC(*this); + retval = pSession->InitializeFromL(*aServiceDescription); + if(retval != KErrNone) + { + CleanupStack::PopAndDestroy(pSession); + return retval; + } +#ifdef _SENDEBUG + TPtrC8 sessionEndpoint = pSession->Endpoint(); + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"Creating ASClient and new Session using Endpoint:"); + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,(sessionEndpoint)); +#endif + + pASClient = CIdWsfAuthenticationServiceClient::NewLC(*this);//, *Log()); + pASClient->SetServiceSessionL(pSession); // pSession will be owned by ASClient + CleanupStack::Pop(2); // pASClient, pSession + CleanupStack::PushL(pASClient); + + retval = Manager().RemoveServiceDescriptionL(*pASClient); + if(retval != KErrNone) + { + delete pASClient; + } + CleanupStack::Pop(); // pASClient + } + + return retval; + } + +TInt CSenIdWsfPlugin::RegisterASClientL( + MSenServiceDescription *aServiceDescription) + { +#ifdef _SENDEBUG + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenIdWsfPlugin::RegisterASClientL"); + TPtrC8 endpoint = aServiceDescription->Endpoint(); + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,(endpoint)); +#endif // _SENDEBUG + + TInt retval = KErrNone; + + CIdWsfServiceSession *pSession = NULL; + CIdWsfAuthenticationServiceClient *pASClient = NULL; + + if(aServiceDescription->DescriptionClassType() == + MSenServiceDescription::EIdWsfAuthenticationServiceClient) + { + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,(_L8("This ServiceDescription is already an AS Client"))); + pASClient = (CIdWsfAuthenticationServiceClient*)aServiceDescription; + + retval = Manager().AddServiceDescriptionL(pASClient); + } + else + { + // Create new Authentication Service client and initialize + // it from given description + pSession = CIdWsfServiceSession::NewLC(*this); + retval = pSession->InitializeFromL(*aServiceDescription); + + if(retval != KErrNone) + { + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenIdWsfPlugin::RegisterASClientL"); + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KNormalLogLevel ,_L("- InitializeFromL(SD) failed: %d"), retval)); + CleanupStack::PopAndDestroy(); // pSession + return retval; + } + else if(pSession->Endpoint() == KNullDesC8) + { + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"- InitializeFromL => KErrSenNoEndpoint"); + CleanupStack::PopAndDestroy(); // pSession + return KErrSenNoEndpoint; + } + +#ifdef _SENDEBUG + TPtrC8 sessionEndpoint = pSession->Endpoint(); + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel , + _L8("- Creating AS client and new session using endpoint: '%S'"), + &sessionEndpoint)); +#endif // _SENDEBUG + + pASClient = CIdWsfAuthenticationServiceClient::NewLC(*this);//, *Log()); + pASClient->SetServiceSessionL(pSession); // pSession will be + // owned by ASClient + CleanupStack::Pop(2); // pASClient, pSession + CleanupStack::PushL(pASClient); + + retval = Manager().AddServiceDescriptionL(pASClient); + if(retval != KErrNone) + { + delete pASClient; + } + CleanupStack::Pop(); // pASClient + } + + return retval; + } + +TInt CSenIdWsfPlugin::RegisterDSClientL( + MSenServiceDescription* aServiceDescription) + { + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,(_L8("RegisterDSClientL(..)"))); + + TInt retval = KErrNone; + + CIdWsfServiceSession *pSession = NULL; + CIdWsfDiscoveryServiceClient *pDSClient = NULL; + + if(aServiceDescription->DescriptionClassType() == + MSenServiceDescription::EIdWsfDiscoveryServiceClient) + { + /* There already is a session, but it may be necessary + * to reset the user information. + */ + pDSClient = (CIdWsfDiscoveryServiceClient*)aServiceDescription; + retval = Manager().AddServiceDescriptionL(pDSClient); + } + else + { + pSession = CIdWsfServiceSession::NewLC(*this); + retval = pSession->InitializeFromL(*aServiceDescription); + if(retval != KErrNone) + { + CleanupStack::PopAndDestroy(); // pSession + return retval; + } +#ifdef _SENDEBUG + TPtrC8 endpoint = pSession->Endpoint(); + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,_L8("Creating DSClient for %S"), &endpoint)); +#endif // _SENDEBUG + + pDSClient = CIdWsfDiscoveryServiceClient::NewLC(*this);//, *Log()); + pDSClient->SetServiceSessionL(pSession); + CleanupStack::Pop(2); // pDSClient, pSession + CleanupStack::PushL(pDSClient); + + retval = Manager().AddServiceDescriptionL(pDSClient); + if(retval != KErrNone) + { + delete pDSClient; + } + CleanupStack::Pop(); // pDSClient + } + return retval; + } + +TInt CSenIdWsfPlugin::UnRegisterDSClientL( + MSenServiceDescription* aServiceDescription) + { + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,(_L8("RegisterDSClientL(..)"))); + + TInt retval = KErrNone; + + CIdWsfServiceSession *pSession = NULL; + CIdWsfDiscoveryServiceClient *pDSClient = NULL; + + if(aServiceDescription->DescriptionClassType() == + MSenServiceDescription::EIdWsfDiscoveryServiceClient) + { + // There already is a session, but it may be necessary + // to reset the user information. + // + pDSClient = (CIdWsfDiscoveryServiceClient*)aServiceDescription; + retval = Manager().RemoveServiceDescriptionL(*pDSClient); + } + else + { + pSession = CIdWsfServiceSession::NewLC(*this); + retval = pSession->InitializeFromL(*aServiceDescription); + if(retval != KErrNone) + { + CleanupStack::PopAndDestroy(); // pSession + return retval; + } +#ifdef _SENDEBUG + TPtrC8 endpoint = pSession->Endpoint(); + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,_L8("Creating DSClient for %S"), &endpoint)); +#endif + + pDSClient = CIdWsfAuthenticationServiceClient::NewLC(*this);//, *Log()); + pDSClient->SetServiceSessionL(pSession); + CleanupStack::Pop(2); // pDSClient, pSession + CleanupStack::PushL(pDSClient); + + retval = Manager().RemoveServiceDescriptionL(*pDSClient); + if(retval != KErrNone) + { + delete pDSClient; + } + CleanupStack::Pop(); // pDSClient + } + return retval; + } + +/** +* Create a ServiceSession based upon the given ServiceDescription. +* The ServiceSession is expected to be "valid", i.e. ready for use +* by a client. +* +* @param aServiceDescription A ServiceDescription +* +* @param aNewSession (CSenServiceSession) +* +* return TInt error or KErrNone if successful +*/ +TInt CSenIdWsfPlugin::CreateServiceSessionL( MSenServiceDescription& aServiceDescription, + MSenServiceDescription& aPattern, + CSenServiceSession*& aNewSession, + MSenRemoteServiceConsumer& aRemoteConsumer, + HBufC8*& /* aErrorMsg */ ) // TODO: start providing aErrorMsg on SOAP faults(!) + { +#ifdef _SENDEBUG + CSLOG(aRemoteConsumer.ConnectionId() , KMinLogLevel,(_L("CreateServiceSessionL()"))); + TPtrC8 contract = aServiceDescription.Contract(); + CSLOG_FORMAT((aRemoteConsumer.ConnectionId() , KMinLogLevel, _L8("- Asked to create ServiceSession using '%S' as Contract...)"), + &contract)); +#endif + + delete aNewSession; + aNewSession = NULL; + + if(aServiceDescription.DescriptionClassType() == MSenServiceDescription::EIdWSFServiceSession) + { + aNewSession = (CIdWsfServiceSession*) &aServiceDescription; + CSLOG_L(aRemoteConsumer.ConnectionId() , KMinLogLevel,"- service description is already an ID-WSF service session."); + // Check for messageThreading! (and other facets that may have to be + // set or cleared) + // We can assume that the current session matches with the pattern + // but that there may be a need to adjust some settings. + ((CIdWsfServiceSession*)aNewSession)->CopyFacetsFromL(aPattern); + } + else + { + aNewSession = (CIdWsfServiceSession*) NewServiceDescriptionL(); + ((CIdWsfServiceSession*)aNewSession)->InitializeFromL( aServiceDescription ); + } + + if(aNewSession) + { + if(!aNewSession->IsReadyL()) + { + if(ValidateL(*((CIdWsfServiceSession*)aNewSession), aRemoteConsumer)) + { + // note (below): sessions were just previously written(!) + // -> due to nature of current CSenXmlDao implementation: + // it writes everything and every time it is saving some + // new object. + Manager().SaveL(*this); + return KErrNone; + } + else + { + return KErrNotReady; + } + } + } + return KErrNone; + } + + +TBool CSenIdWsfPlugin::ValidateL(CIdWsfServiceSession& aSession, + MSenRemoteServiceConsumer& aRemoteConsumer) + { +#ifdef _SENDEBUG + TPtrC8 endpoint = aSession.Endpoint(); + CSLOG_FORMAT((aRemoteConsumer.ConnectionId() , KMinLogLevel, _L8("Session to '%S' Endpoint needs to be revalidated!"), + &endpoint)); +#endif // _SENDEBUG + + CIdWsfDiscoveryServiceClient* pDSClient = NULL; + TPtrC8 trustAnchor = aSession.TrustAnchor(); + pDSClient = DSClientL(trustAnchor, aRemoteConsumer); + + if(!pDSClient) + { + // this typically occurs, if no IDP was obtained + // the file might have been empty, or no matching + // IDP was found(!) + return EFalse; + } + + TInt retVal = pDSClient->ValidateL(aSession, aRemoteConsumer); + + TBool success = (retVal == KErrNone) && aSession.IsReadyL(); + if(success) + { + // note (above): this leads to instant, second-time-write of sessions + // -> due to nature of current CSenXmlDao implementation: + // it writes everything and every time it is saving some new object. + Manager().SaveL(aSession); + } + + return success; + } + + +CIdWsfDiscoveryServiceClient* CSenIdWsfPlugin::DSClientL( + const TDesC8& aTrustAnchor, + MSenRemoteServiceConsumer& aRemoteConsumer) + { + CSLOG(aRemoteConsumer.ConnectionId() , KMinLogLevel,(_L("DSClientL(const TDesC& aTrustAnchor, MSenRemoteServiceConsumer&)"))); + CSenIdentityProvider* pIdentityProvider = IdentityProviderL(aTrustAnchor); + if(pIdentityProvider) + { + return DSClientL(pIdentityProvider, aRemoteConsumer); + } + else + { + return NULL; + } + } + + +CSenIdentityProvider* CSenIdWsfPlugin::IdentityProviderL( + const TDesC8& aProviderId) + { + CIdWsfServiceInstance *pPattern = CIdWsfServiceInstance::NewLC(); + pPattern->SetProviderIdL( aProviderId ); + + // 2004-08-10. one-line fix // this is checked by ID-MGR for matches + if(aProviderId.Length()>0) + { + pPattern->SetEndPointL( aProviderId ); + } + + CSenIdentityProvider* pIdentityProvider = IdentityProviderL( pPattern ); + CleanupStack::PopAndDestroy( pPattern ); + + return pIdentityProvider; + + } + +CSenIdentityProvider* CSenIdWsfPlugin::IdentityProviderL( + MSenServiceDescription* aPattern) + { + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenIdWsfPlugin::IdentityProviderL"); + + CSenIdentityProvider* pIdentityProvider = NULL; + + if(aPattern) + { + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"Querying IdentityProvider using a pattern."); + pIdentityProvider = Manager().IdentityProviderL(*aPattern); + } + else + { + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"No pattern given for IdentityProvider query."); + } + + if(!pIdentityProvider) + { + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"Querying IdentityProvider without a pattern."); + pIdentityProvider = Manager().IdentityProviderL(); + } + +#ifdef _SENDEBUG + if(!pIdentityProvider) + { + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"FATAL: Did not obtain an IdentityProvider!"); + } +#endif + + return pIdentityProvider; + } + +TBool CSenIdWsfPlugin::ValidateDSL(CIdWsfDiscoveryServiceClient* aDSClient, + CSenIdentityProvider* aIDP, + MSenRemoteServiceConsumer& aRemoteConsumer) + { + CIdWsfAuthenticationServiceClient *pASClient = ASClientL(aIDP); + if(!pASClient) + { + return EFalse; + } + + CIdWsfServiceSession* pSession = aDSClient->IdWsfServiceSession(); + if(pSession) + { + pASClient->ValidateL(*pSession, aRemoteConsumer); + } + return aDSClient->IsReadyL(); + } + +/** +* Obtain or construct a valid DiscoveryServiceClient. Ask +* the owning ServiceManager for ServiceDescriptions that match +* the ID-WSF Discovery Service contract, and that have the +* given trust anchor (aIdentityProvider). +* if given. +* +* @param aIdentityProvider +* @return DiscoveryServiceClient +*/ +CIdWsfDiscoveryServiceClient* CSenIdWsfPlugin::DSClientL( + CSenIdentityProvider* aIdentityProvider, + MSenRemoteServiceConsumer& aRemoteConsumer) + { + CSLOG(aRemoteConsumer.ConnectionId() , KMinLogLevel,(_L("DSClientL(CSenIdentityProvider*, MSenRemoteServiceConsumer&)"))); + + TPtrC8 trustAnchor(KNullDesC8); + if(aIdentityProvider) + { + trustAnchor.Set(aIdentityProvider->ProviderID()); + } + + CIdWsfDiscoveryServiceClient* pDSClient = NULL; + + RPointerArray matches; + CleanupClosePushL(matches); + + CoreServiceDescriptionsL(matches, KIdWsfFrameworkDiscoveryServiceContract, + KNullDesC8); + CSLOG(aRemoteConsumer.ConnectionId() , KMinLogLevel,(_L(">>> TrustAnchor to match:"))); + + CSLOG(aRemoteConsumer.ConnectionId() , KMaxLogLevel,(trustAnchor)); + + // we now should have DiscoveryServiceClients or nothing + for(TInt i = 0; i < matches.Count(); i++) + { + CIdWsfDiscoveryServiceClient* pCandidate = + reinterpret_cast(matches[i]); + + if(pCandidate && trustAnchor.Length()>0) + { + TPtrC8 candidatesTrustAnchor = pCandidate->TrustAnchor(); + CSLOG(aRemoteConsumer.ConnectionId() , KMaxLogLevel,(_L(">>> DS Candidate TrustAnchor:"))); + CSLOG(aRemoteConsumer.ConnectionId() , KMaxLogLevel,(candidatesTrustAnchor)); + + if(candidatesTrustAnchor.Length() == 0 || + trustAnchor != candidatesTrustAnchor) + { + CSLOG(aRemoteConsumer.ConnectionId() , KMinLogLevel,(_L(">>> DS Candidate not trusted"))); + pCandidate = NULL; + } + } + + if(pCandidate) + { + CSLOG(aRemoteConsumer.ConnectionId() , KMinLogLevel,(_L(">>> DS Candidate trusted"))); + if(!pDSClient) + { + pDSClient = pCandidate; + } + else if(pCandidate->ValidUntilL() > pDSClient->ValidUntilL()) + { + CSLOG(aRemoteConsumer.ConnectionId() , KMinLogLevel,(_L("Found: Discovery Service Session having longer validity!"))); + pDSClient = pCandidate; + } + } + } + + if(!pDSClient) + { + /* Obtain an AuthenticationServiceClient and ask it to validate + * a new DiscoveryServiceClient. + */ + pDSClient = CIdWsfDiscoveryServiceClient::NewLC(*this);//, *Log()); + CIdWsfServiceSession* pBrandNewSession = + CIdWsfServiceSession::NewL(*this); + + // The SetServiceSessionL() will also set the DS client + // as the first consumer of this new service session. + // Ownership of pBrandNewSession is transferred to pDSClient: + pDSClient->SetServiceSessionL(pBrandNewSession); + + // NOTE + // + // This policy related feature is in still in progress, and + // therefore: NO ready implementation has been provided. + // + // add the _REAL_ consumer to assure policy transaction(!) + //pBrandNewSession->AddConsumerL(aRemoteConsumer); + // + // NOTE + + CIdWsfAuthenticationServiceClient* pASClient = + ASClientL(aIdentityProvider); + if(pASClient) + { + CIdWsfServiceSession* pSession = pDSClient->IdWsfServiceSession(); + if(pSession) + { + pASClient->ValidateL(*pSession, aRemoteConsumer); + } + } + + if(pDSClient->IsReadyL()) + { + TInt retVal = Manager().AddServiceDescriptionL(pDSClient); + if(retVal != KErrNone) + { + CleanupStack::PopAndDestroy(); // pDSClient + pDSClient = NULL; + } + else + { + CleanupStack::Pop(); // pDSClient + } + } + else + { + // bugfix 2005-03-02, matmatt + CleanupStack::PopAndDestroy(); // pDSClient + pDSClient = NULL; // not valid + } + } + else + { + if(!pDSClient->IsReadyL()) + { + CIdWsfAuthenticationServiceClient* pASClient = + ASClientL(aIdentityProvider); + if(pASClient) + { + CIdWsfServiceSession* pSession = pDSClient->IdWsfServiceSession(); + if(pSession) + { + pASClient->ValidateL(*pSession, aRemoteConsumer); + } + } + + if(pDSClient->IsReadyL()) + { + Manager().SaveL(*this); + } + else + { + pDSClient = NULL; // not valid, fixed 2005-12-07 + } + } + } + CleanupStack::PopAndDestroy(); //matches.Close(); + + return pDSClient; + } + +/** +* Obtain or construct a valid AuthenticationServiceClient. Ask +* the owning ServiceManager for ServiceDescriptions that match +* the ID-WSF Authentication Service contract, and the ProviderID +* of the ServiceDescription, if given. +* +* @param providerID +* @return AuthenticationServiceClient +*/ +CIdWsfAuthenticationServiceClient* CSenIdWsfPlugin::ASClientL( + CSenIdentityProvider* aIdentityProvider) + { + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,(_L8("ASClientL(..)"))); + + TPtrC8 providerId(KNullDesC8); + if(aIdentityProvider) + { + providerId.Set(aIdentityProvider->ProviderID()); + } + + if(providerId.Length()>0) + { + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,_L8("Searching for AS at %S"), &providerId)); + } + else + { + TLSLOG(KSenCoreServiceManagerLogChannelBase , KNormalLogLevel ,(_L8("Searching for AS at NULL"))); + } + + CIdWsfAuthenticationServiceClient* pASClient = NULL; + + RPointerArray matches; + CleanupClosePushL(matches); + + CoreServiceDescriptionsL(matches, + KIdWsfFrameworkAuthenticationServiceContract(), + providerId); + + if(matches.Count() > 0) + { + pASClient = + reinterpret_cast(matches[0]); + pASClient->SetAccount(aIdentityProvider); + } + else + { + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,(_L("No matching AS description available!"))); + } + + if(matches.Count() > 1) + { + // search for a instance with longest validity + for(TInt i = 0; i < matches.Count(); i++) + { + CIdWsfAuthenticationServiceClient* pNewerASClient = + reinterpret_cast(matches[i]); + pNewerASClient->SetAccount(aIdentityProvider); + if(pNewerASClient->ValidUntilL() > pASClient->ValidUntilL()) + { + pASClient = pNewerASClient; + } + } + } + + CleanupStack::PopAndDestroy(); // matches.Close(); + return pASClient; + } + +TInt CSenIdWsfPlugin::CoreServiceDescriptionsL( + RPointerArray& aMatches, + const TDesC8& aContract, + const TDesC8& aProviderID) + { + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,(_L8("CoreServiceDescriptionsL(..)"))); + + RPointerArray serviceDescriptions; + CleanupClosePushL(serviceDescriptions); + + TInt retVal = + Manager().ServiceDescriptionsL(serviceDescriptions, aContract); + if(retVal != KErrNone) + { + return retVal; + } + + CIdWsfCoreServiceConsumer* pDescription = NULL; + for(TInt i = 0; i < serviceDescriptions.Count(); i++) + { + pDescription = (CIdWsfCoreServiceConsumer*)serviceDescriptions[i]; + if(aProviderID.Length()>0) + { +#ifdef _SENDEBUG + HBufC8* pAsXml = pDescription->AsXmlL(); + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenIdWsfPlugin::CoreServiceDescriptionsL:"); + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMaxLogLevel ," - CoreServiceConsumer as XML:"); + if(pAsXml) + { + CleanupStack::PushL(pAsXml); + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMaxLogLevel ,(*pAsXml)); + CleanupStack::PopAndDestroy(); // asXml + } +#endif + + TPtrC8 providerID = pDescription->ProviderId(); + if(providerID.Length()>0 && (aProviderID == providerID)) + { +#ifdef _SENDEBUG + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMaxLogLevel ,(_L8(" > added to matches"))); +#endif + aMatches.Append(pDescription); + } + } + else + { + aMatches.Append(pDescription); + } + } + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KNormalLogLevel ,_L8("Found %d matches for"), aMatches.Count())); + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,_L8(" a contract: %S"), &aContract)); + + CleanupStack::PopAndDestroy(); // serviceDescriptions.Close(); + return KErrNone; + } + +/** +* Return a new instance of a framework specific class that +* implements the ServiceDesccription interface. +* +* @param aNewSession (CSenServiceSession) +* +* return TInt error or KErrNone if successful +*/ +CSenWSDescription* CSenIdWsfPlugin::NewServiceDescriptionL() + + { + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,(_L8("CSenIdWsfPlugin::NewServiceDescriptionL()"))); + CIdWsfServiceSession* pSD = CIdWsfServiceSession::NewL(*this); + return pSD; + } + +/** +* Return the ServiceManager for which this instance is working. +* This is used by the ServiceSession instances created by this framework. +* +* Note, in Sen, MSenCoreServiceManager so all Frameworks +* return their "owner" - i.e. - the only service manager in Sen Framework +* +* @return (MSenCoreServiceManager) +*/ +MSenCoreServiceManager& CSenIdWsfPlugin::Manager() + { + return iManager; + } + +/** +* Set the ServiceManager to which this instance reports. +* The (singleton) ServiceManager calls this method when +* it instantiates a framework. +* +* @param aServiceManager The singleton ServiceManager in the system. +*/ +void CSenIdWsfPlugin::SetManager(MSenCoreServiceManager& aServiceManager) + { + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,(_L8("CSenIdWsfPlugin::SetManager(.)"))); + iManager = aServiceManager; + } + + +/** +* Return an object that can do SAX based parsing of a XML fragment +* that contains framework specific configuration information. +* The ServiceManager asks for this BaseFragment upon startup +* in order to give this framework a chance to read its configuration +* information from the central ServiceManager configuration document. +* +* @return (CSenBaseFragment) +*/ +CSenBaseFragment& CSenIdWsfPlugin::ConfigParser() + { + TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,(_L8("CSenIdWsfPlugin::ConfigParser()"))); + return *this; + } + +/** +* Write the ServiceInvocationFramework configuration as XML to a HBufC8. +* +* This method is invoked by the ServiceManager when it saves +* its state and/or configuration. +* +* Upon startup the chunk of XML that is written will be passed back to +* the configuation parser of the framework. +* +* The "schema" that shall be adhered to is: +*
+* <element name="Framework">
+*       <any/><!-- this is where implementations write additional
+*       information -->
+*       <attribute name="class" type="String">
+*    <!-- In Symbian the class attribute is used as cue for
+*    the ECOM Resolver -->
+* </element>
+* 
+* +* @param aTo - a HBufC8 to which the framework should write its configuration +*/ + + +void CSenIdWsfPlugin::EndElementL(const TDesC8& aNsUri, + const TDesC8& aLocalName, + const TDesC8& aQName) + { + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel , + _L8("ID-WSF plugin @ end of element: %S (xmlns='%S', localname='%S')"), + &aQName, &aNsUri, &aLocalName)); + CSIF::EndElementL(aNsUri,aLocalName,aQName); + } + +// over-ride CSenBaseFragment +HBufC* CSenIdWsfPlugin::AsXmlUnicodeL() + { + HBufC8* pUtf8 = AsXmlL(); + CleanupStack::PushL(pUtf8); + HBufC* pAsAxlInUnicode = SenXmlUtils::ToUnicodeLC(*pUtf8); + CleanupStack::Pop(); // pAsAxlInUnicode + CleanupStack::PopAndDestroy(); // pUtf8 + return pAsAxlInUnicode; + } + +HBufC8* CSenIdWsfPlugin::AsXmlL() + { + _LIT8(KFramework,"\n"); + HBufC8* retVal = HBufC8::NewLC(256); + TPtr8 ptr = retVal->Des(); + ptr.Append(KFramework); // Codescanner warnings + ptr.Append(KXmlns); + ptr.Append(KIdWsfFrameworkXMLNS); + ptr.Append(KQuot); + + ptr.Append(KClass); + ptr.Append(KIdWsFrameworkCue); + ptr.Append(KClosedTag); + CleanupStack::Pop(); // retVal + return retVal; + } + +TInt CSenIdWsfPlugin::OnEvent(const TInt aEvent, + TAny* /* aArgument */) + { + TInt retVal(KErrNone); + TInt leaveCode(KErrNone); + switch(aEvent) + { + case KSenEventWsfReady: + // Core constructed + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"KSenEventWsfReady"); + { + TRAP(leaveCode, retVal = AssignSessionValidatorsL()); + } + break; + case KSenEventIdWsfSessionValidatorRequested: + { + // Someone needs validator + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"KSenEventIdWsfSessionValidatorRequested"); + TRAP(leaveCode, retVal = AssignSessionValidatorsL()); + } + break; +#ifdef _SENDEBUG + default: + { + //TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"==> no action taken."); + } + break; +#endif // _SENDEBUG + } + // if leave occurred, return leave code instead + if(leaveCode) + { + retVal = leaveCode; + } + + return retVal; + } + +TAny* CSenIdWsfPlugin::ExtendedInterface() + { + // there is no extended interface in ID-WSF framework at the moment + return NULL; + } + +TInt CSenIdWsfPlugin::AssignSessionValidatorsL() + { + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenIdWsfPlugin::AssignSessionValidatorsL()"); + + CSenWSDescription* pOpenMask = CSenWSDescription::NewLC( + KNullDesC8, KNullDesC8); // this matches with *any* ServDescription + pOpenMask->SetFrameworkIdL(KDefaultIdWsfFrameworkID); + + RWSDescriptionArray all; + iManager.ServiceDescriptionsL(all, *pOpenMask); + CleanupClosePushL(all); + + RWSDescriptionArray asClients; + iManager.ServiceDescriptionsL(asClients, + KIdWsfFrameworkAuthenticationServiceContract); + CleanupClosePushL(asClients); + + RWSDescriptionArray dsClients; + iManager.ServiceDescriptionsL(dsClients, + KIdWsfFrameworkDiscoveryServiceContract); + CleanupClosePushL(dsClients); + + TInt count(all.Count()); + TInt asCount(asClients.Count()); + TInt dsCount(dsClients.Count()); + + for(TInt i=0; iDescriptionClassType() == + MSenServiceDescription::EIdWSFServiceSession) + { + CIdWsfServiceSession* pSession = (CIdWsfServiceSession*)pSD; + if(!pSession->Validator() && pSession->TrustAnchor().Length()>0) + { + // session does not have validator, attempt to find one + for(TInt d=0; dDescriptionClassType() == + MSenServiceDescription::EIdWsfDiscoveryServiceClient) + { + CIdWsfDiscoveryServiceClient* pDsClient = + (CIdWsfDiscoveryServiceClient*)dsClients[d]; + TPtrC8 trustAnchor = pSession->TrustAnchor(); + if(trustAnchor == pDsClient->TrustAnchor()) + { + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KNormalLogLevel ,_L8("Validator (DSC): 0x%x"), pDsClient)); + pSession->SetValidator(pDsClient); + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KNormalLogLevel ,_L8("Validator (DSC): 0x%x"), pDsClient)); + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KNormalLogLevel ,_L8("Validator for ID-WSF session found, trustanchor: %S"), &trustAnchor)); + d = dsCount; // break this loop + } + } + + } + } + } + + if(pSD->DescriptionClassType() == + MSenServiceDescription::EIdWsfDiscoveryServiceClient) + { + CIdWsfDiscoveryServiceClient* pDsClient = + (CIdWsfDiscoveryServiceClient*)pSD; + if(!pDsClient->Validator() && + pDsClient->TrustAnchor().Length()>0) + { + // session does not have validator, attempt to find one + for(TInt a=0; aDescriptionClassType() == + MSenServiceDescription::EIdWsfAuthenticationServiceClient) + { + CIdWsfAuthenticationServiceClient* pAsClient = + (CIdWsfAuthenticationServiceClient*)asClients[a]; + + TPtrC8 trustAnchor = pDsClient->TrustAnchor(); + + if(trustAnchor == pAsClient->ProviderId()) + { + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,_L8("Validator (ASC): 0x%x"), pAsClient)); + CSenIdentityProvider* pAccount = + IdentityProviderL(pAsClient->ProviderId()); + if(pAccount) + { + pAsClient->SetAccount(pAccount); + //pDsClient->SetValidator(pAsClient); + + pDsClient->IdWsfServiceSession()->SetValidator(pAsClient); + //pAsClient->ValidateL(*pDsClient->IdWsfServiceSession()); // TEST ONLY!!!!! + a = asCount; // break the loop, validator was found + TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,_L8("Validator for DS client found, trustanchor: %S"), &trustAnchor)); + } +#ifdef _SENDEBUG + else + { + TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"Account (IDP) for ASC not found! No DS validator available"); + } +#endif + } + } + + } + } + } + } + + CleanupStack::PopAndDestroy(4); // close dsClients, close asClients + // close all, delete pOpenMask + return KErrNone; + } + +TInt CSenIdWsfPlugin::SetTransportPropertiesL(MSenTransport& aTransport) + { + //CSenHttpTransportProperties* pProps = CSenHttpTransportProperties::NewLC(); + CSenTransportProperties* pProps = CSenTransportProperties::NewLC(); + pProps->SetPropertyL(KSenSoapActionHeaderName, KSenSoapActionHeaderValueEmpty, KHttpHeaderType); + HBufC8* pPropsAsXml = pProps->AsUtf8L(); + CleanupStack::PopAndDestroy(pProps); + + CleanupStack::PushL( pPropsAsXml ); + // In ID-WSF, even message layer will be forced to have an empty SOAPAction value(!), only + // the message's transport properties sent by consumer applicatoin may override this + // (although they never should do that, it has been made possible for the application messages). + TInt retVal = aTransport.SetPropertiesL( *pPropsAsXml, MSenLayeredProperties::ESenMessageLayer, NULL ); + TInt retVal2 = aTransport.SetPropertiesL( *pPropsAsXml, MSenLayeredProperties::ESenFrameworkLayer, NULL ); + CleanupStack::PopAndDestroy( pPropsAsXml ); + return retVal