/*
* Copyright (c) 2006-2006 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
#include "wsstarservicesession.h"
#include "sendebug.h"
#include "senlogger.h"
#include "SenSoapFault.h"
#include "senservicemanagerdefines.h"
#include "SenServiceConnection.h" // err code definitions
#include "senserviceinvocationframework.h"
#include "SenHttpTransportProperties.h"
#include "senvtcptransportproperties.h"
#include "SenDateUtils.h"
#include "wsstarpolicy.h"
#include "sendebug.h"
#include "sencryptoutils.h"
#include "senwspattern.h"
#include "SenXmlUtils.h"
#include <xmlengnodelist.h>
#include <SenIdentityProvider.h>
#include "wsstarcredentialobserver.h"
using namespace WSPolicy;
/* Constant margin. Value is copied from framework internal class.
* We check if MT is expired (now < validUntil - skew time - margin)
* Margin is 15 minutes.
*/
const TInt64 KClockSlipMinutes = 15;
CWSStarServiceSession* CWSStarServiceSession::NewL(MSIF& aFramework)
{
CWSStarServiceSession* self = CWSStarServiceSession::NewLC(aFramework);
CleanupStack::Pop(self);
return self;
}
CWSStarServiceSession* CWSStarServiceSession::NewLC(MSIF& aFramework)
{
CWSStarServiceSession* self = new (ELeave) CWSStarServiceSession(
MSenServiceDescription::EWSStarServiceSession, aFramework);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
CWSStarServiceSession::CWSStarServiceSession(TDescriptionClassType aType,
MSIF& aSIF)
: CSenWebServiceSession(aType, aSIF),
iMessageThread(EFalse),
iSubmitState(WSStarSession::KSubmitStateOK)
{
}
CWSStarServiceSession::~CWSStarServiceSession()
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::~CWSStarServiceSession");
delete iSessionContext;
delete iProviderID;
delete iTrustAnchor;
delete iOutContext;
delete iInContext;
delete ipReceivedMessageIdInTrans;
delete iTransProp;
TInt count(iConsumerList.Count());
TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel, _L8("CWSStarServiceSession::~CWSStarServiceSession leaved ConsumerL now= %d"), count));
for(TInt i=0; i<count; i++)
{
// we can assume that every remote consumer
// has been wrapped inside WSStarSessionConsumer
// -wrapperclass. Cast and destroy:
CWSStarSessionConsumer* pConsumer
= (CWSStarSessionConsumer*) iConsumerList[i];
// this destroys the wrapper, but the remote
// consumer objects ownership remains in either
// XMLDao or ClientSession (etc)
delete pConsumer;
}
delete iTicketObs;
}
void CWSStarServiceSession::ConstructL()
{
CSenWebServiceSession::ConstructL();
iTicketObs = CWSStarCredentialObserver::NewL(this, iFramework.Manager().Log());
}
TInt CWSStarServiceSession::AddConsumerL(MSenRemoteServiceConsumer& aConsumer)
{
CSLOG_L(aConsumer.ConnectionId() ,KMinLogLevel ,"CWSStarServiceSession::AddConsumerL");
const TInt consumerCount(iConsumerList.Count());
for(TInt i=0; i<consumerCount; i++)
{
if(iConsumerList[i]->Id() == aConsumer.Id())
{
return KErrAlreadyExists; // already added, nothing to do
}
}
CWSStarSessionConsumer* pSessionConsumer =
CWSStarSessionConsumer::NewL(aConsumer, *Log());
TInt error = iConsumerList.Append(pSessionConsumer);
CWSStarPlugin* fmw = (CWSStarPlugin*)&iFramework;
fmw->PolicyConsumerAddedL(this,*pSessionConsumer);
return KErrNone;
}
/**
* DetachCredentialsL
*
* This function invalidates the session by deleting the credential
* This also call setStatusL to recompute the status
*/
void CWSStarServiceSession::DetachCredentialsL()
{
ClearCredentialL() ;
SetStatusL() ;
}
TBool CWSStarServiceSession::ExistConsumerL()
{
const TInt consumerCount(iConsumerList.Count());
if( consumerCount == 0 )
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KNormalLogLevel," - Consumer count = 0");
return EFalse;
}
else
{
TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KNormalLogLevel, _L8("- Consumer count = %d"), consumerCount));
return ETrue;
}
}
TInt CWSStarServiceSession::RemoveConsumerL(MSenRemoteServiceConsumer& aConsumer)
{
CSLOG_L(aConsumer.ConnectionId() ,KMinLogLevel ,"CWSStarServiceSession::RemoveConsumerL:");
const TInt consumerCount(iConsumerList.Count());
for(TInt i=0; i<consumerCount; i++)
{
if(iConsumerList[i]->Id() == aConsumer.Id())
{
CWSStarSessionConsumer* pConsumer
= (CWSStarSessionConsumer*) iConsumerList[i];
delete pConsumer;
iConsumerList.Remove(i);
CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel , _L8("CWSStarServiceSession::Removed ConsumerL now= %d"), consumerCount-1));
if( (consumerCount-1) == 0 )
{
iTicketObs->Cancel();
}
break;
}
}
// If this session has no consumers, we can hold our grip to the credential
// (note: this does NOT mean that credential is removed, not at all(!), but
// that new search for the credential has to be performed).
if( consumerCount == 0 )
{
CSLOG_L(aConsumer.ConnectionId() ,KNormalLogLevel ,"- Consumer count == 0");
CSLOG_L(aConsumer.ConnectionId() ,KNormalLogLevel ,"-> Closing the handle to the credential owned by the Credential Manager.");
SetSecurityL(KNullDesC8); // this removes the reference to credential, but
// it can be regained on next lookup
// This needs to implemet. so that userinfo (password)
// that grants the permission to use the credential
// will be checked on that (credential sharing) lookup.
}
return CSenServiceSession::RemoveConsumerL(aConsumer);
}
TInt CWSStarServiceSession::MessageForSendingL( const TDesC8& aBody,
const TDesC8& aSenderID,
CSenSoapMessage*& aMessage)
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::MessageForSendingL");
TInt error(KErrNone);
if (AmIHostletSession())
{
return CSenWebServiceSession::MessageForSendingL(aBody, aSenderID, aMessage);
}
else
{
CleanupStack::PushL(aMessage);
CWSStarSessionConsumer* pConsumer = NULL;
//senderID is internal id of consumer
error = SessionConsumerL(aSenderID, pConsumer);
if (error)
{
CleanupStack::Pop(aMessage);
return error;
}
CWSStarSessionContext* ssCtx = (CWSStarSessionContext*)SessionContext();
//----adding addressing info
//messageId - set by handler
User::LeaveIfError(iOutContext->Add(WSStarContextKeys::KTo, Contract()));
if(ipReceivedMessageIdInTrans)
{
User::LeaveIfError(iOutContext->Add(WSStarContextKeys::KRelatesTo,
*ipReceivedMessageIdInTrans));
}
else
{
User::LeaveIfError(iOutContext->Add(WSStarContextKeys::KRelatesTo, NULL));
}
iOutContext->SetOwnedEnvelope();
iOutContext->UpdateFromSessionContextL(*ssCtx);
CleanupStack::Pop(aMessage);
error = ((CWSStarPlugin&)iFramework).ProcessOutboundMessageL(
iOutContext, &aBody, aMessage);
iSessionContext->UpdateFromMessageOutContextL(*iOutContext);
const TDesC8* resolvedBody = iSessionContext->GetDesC8L(WSStarContextKeys::KBody);
if (resolvedBody && (!error))
{
error = pConsumer->MessageForSendingL(*resolvedBody , iOutContext);
}
aMessage = iOutContext->GetCurrentSoapMessage();
iOutContext->SetOwnedEnvelope(EFalse);
delete iOutContext;
iOutContext = NULL;
}
return error;
}
TInt CWSStarServiceSession::NewMessageL(CSenSoapMessage*& aMessage)
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::NewMessageL( CSenSoapMessage*& )");
//method used during ibound processing
const TInt* soapVer = iSessionContext->GetIntL(WSStarContextKeys::KSoapVersion);
if (soapVer)
{
aMessage = CSenSoapMessage::NewL((TSOAPVersion)*soapVer);
}
else
{
aMessage = CSenSoapMessage::NewL(ESOAP12);
}
CSenXmlReader* reader = XmlReader();
if (iInContext)
{
delete iInContext;
iInContext = NULL;
}
iInContext = CWSStarMessageContext::NewL(SenContext::EIncoming, reader);
CWSStarSessionContext* ssCtx = (CWSStarSessionContext*)SessionContext();
iInContext->UpdateFromSessionContextL(*ssCtx);
return KErrNone;
}
TInt CWSStarServiceSession::ParseMessageL(CSenSoapMessage& aSOAPMessage)
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::ParseMessageL(CSenSoapMessage& )");
//-----SCHarF ------- 7.5.3.3 Inbound messageflow
//CSenXmlReader* reader = XmlReader();
CSenSoapMessage* soapMessage = &aSOAPMessage;
((CWSStarPlugin&)iFramework).ProcessInboundDispatchL(this, soapMessage);
((CWSStarPlugin&)iFramework).ProcessInboundMessageL(iInContext, soapMessage);
iServerTime.UniversalTime();
//keep transaction chain
if (iMessageThread)
{
const TDesC8* msgId = iInContext->GetDesC8L(WSStarContextKeys::KMessageID());
if (msgId)
{
delete ipReceivedMessageIdInTrans;
ipReceivedMessageIdInTrans = NULL;
ipReceivedMessageIdInTrans = msgId->AllocL();
}
else
{
//transaction mode is enabled, but no messageId in response so what to do.
//anyway we will continue without signalizing error
}
}
iSessionContext->UpdateFromMessageInContextL(*iInContext);
return CSenWebServiceSession::ParseMessageL(aSOAPMessage);
}
TInt CWSStarServiceSession::SendSoapMessageToConsumerL( CSenSoapMessage* apMessage,
const TInt aTxnId,
MSenRemoteServiceConsumer& aConsumer,
MSenProperties* aResponseTransportProperties )
{
//-----SCHarF ------- glue with dispather for handlers 7.5.3.2 inbound
CSLOG_L(aConsumer.ConnectionId() ,KMinLogLevel ,"CWSStarServiceSession::SendSoapMessageToConsumerL");
if ( apMessage )
{
CleanupStack::PushL( apMessage );
//dispatch to proper consumer
CWSStarSessionConsumer* pConsumer = NULL;
SessionConsumerL( iInContext, pConsumer );
if (!pConsumer)
{
CleanupStack::PopAndDestroy( apMessage ); // de-alloc immediately! Change this, if WS-stack one day gives back faults to Service Connections
// No related consumer, signalize fault error
aConsumer.HandleErrorL( NULL, KErrSenBrokenSoapEnvelope, aTxnId, aResponseTransportProperties );
}
else
{
// handle message destroys this
TBool completeServerMessages;
HasFacetL(KCompleteMessagesFacet, completeServerMessages);
CleanupStack::Pop( apMessage ); // REQUIREMENT for next method => it MUST take ownership IMMEDIATELY
pConsumer->HandleSoapMessageL( apMessage, aTxnId, aResponseTransportProperties, completeServerMessages );
}
iRetryCounter = 0; //reset counter for retryAfter faults. If proper message incomes, we can reset counter
iRenewCounter = 0; //
iRedirectCounter =0 ;
delete iInContext;
iInContext = NULL;
return KErrNone;
}
else
{
CSLOG_L(aConsumer.ConnectionId() ,KMinLogLevel ,"CWSStarServiceSession::SendSoapMessageToConsumerL - apMessage == NULL => invoking remote consumer's HandleErrorL with KErrSenBrokenSoapEnvelope");
/*TInt retVal = */ aConsumer.HandleErrorL( NULL, KErrSenBrokenSoapEnvelope, aTxnId, aResponseTransportProperties );
return KErrSenInternal;
}
}
MSenRemoteServiceConsumer* CWSStarServiceSession::RemoteConsumerL( const TDesC8& aSenderID )
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::RemoteConsumerL");
TInt consumersCount(iConsumerList.Count());
for(TInt i=0; i<consumersCount; i++)
{
if(iConsumerList[i]->Id() == aSenderID)
{
return iConsumerList[i];
}
}
return NULL; // not found
}
//---------------------------------------------------------------------------
// To obtain consumer during processing INBOUND.
//---------------------------------------------------------------------------
//
TInt CWSStarServiceSession::SessionConsumerL( CWSStarMessageContext*& aMsgCtx,
CWSStarSessionConsumer*& aSessionConsumer )
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::SessionConsumerL");
TInt consumersCount(iConsumerList.Count());
TInt error(KErrNotFound);
const TDesC8* relatesTo = aMsgCtx->GetDesC8L(WSStarContextKeys::KRelatesTo);
const TDesC8* endpoint = aMsgCtx->GetDesC8L(WSStarContextKeys::KTo);
for(TInt i=0; i<consumersCount; i++)
{
CWSStarSessionConsumer* pConsumer = (CWSStarSessionConsumer*)iConsumerList[i];
if ((relatesTo) && (pConsumer->Expects(*relatesTo, endpoint)))
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::SessionConsumerL - Found consumer");
aSessionConsumer = pConsumer;
error = KErrNone;
break;
}
}
if (error && consumersCount)
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KNormalLogLevel,"CWSStarServiceSession::SessionConsumerL - consumer was not found - using the 1st one (as default)");
aSessionConsumer = (CWSStarSessionConsumer*)iConsumerList[0];
error = KErrNone;
}
return error;
}
//---------------------------------------------------------------------------
// To obtain consumer during processing OUTBOUND.
//---------------------------------------------------------------------------
//
TInt CWSStarServiceSession::SessionConsumerL( const TDesC8& aSenderID,
CWSStarSessionConsumer*& aSessionConsumer )
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::SessionConsumerL");
aSessionConsumer = (CWSStarSessionConsumer*) RemoteConsumerL(aSenderID);
if(aSessionConsumer)
{
return KErrNone;
}
else
{
return KErrNotFound;
}
}
// SYNC IMPLEMENTATION(!) - only available internally.
// It means, that all SYNC operation for 3rd developer from public API are in fact ASYNC.
// @see SenServiceConnectionImpl.cpp
// aSOAPMessage.IsFault() should always be TRUE.
//
TInt CWSStarServiceSession::HandleSoapFaultL( CSenSoapMessage* apSOAPMessage,
HBufC8*& aResponse )
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::HandleErrorL(CSenSoapMessage&, HBufC8*&)");
TInt retVal(KErrNone);
if ( apSOAPMessage )
{
CleanupStack::PushL( apSOAPMessage ); // ownerhip is here
TInt answer = CanHandleErrorL();
if (answer == KErrSenResendRequired)
{
CleanupStack::PopAndDestroy( apSOAPMessage ); // not needed atm
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CanHandleErrorL == TRUE");
CWSStarSessionConsumer* pConsumer = NULL;
// this takes care of messageIDs
retVal = SessionConsumerL(iInContext, pConsumer);
if(!pConsumer)
{
CleanupStack::PopAndDestroy( apSOAPMessage );
return KErrNotFound;
}
const TDesC8* relatesTo = iInContext->GetDesC8L(WSStarContextKeys::KRelatesTo);
if (!relatesTo)
{
//if response from backend doesn't include any relatesTo we can try assume
// that response is for last outgoing message. This trick is used by passport phase
const TInt* isPassportEnabled = iInContext->GetIntL(WSStarContextKeys::KPassportEnabled);
if (isPassportEnabled && *isPassportEnabled == TRUE)
{
relatesTo = iSessionContext->GetDesC8L(WSStarContextKeys::KMessageID);
}
}
if (relatesTo)
{
TDesC8* pBody = pConsumer->BodyL(*relatesTo);
if (pBody)
{
HBufC8* pTemp = HBufC8::NewLC(pBody->Length());
TPtr8 temp = pTemp->Des();
temp.Append(*pBody);
HBufC8* startBody = HBufC8::NewLC(KSenSoapEnvelopeBodyQName().Length()+
KSenLessThan().Length()+
KSenGreaterThan().Length());
TPtr8 startBodyPtr = startBody->Des();
startBodyPtr.Append(KSenLessThan());
startBodyPtr.Append(KSenSoapEnvelopeBodyQName());
startBodyPtr.Append(KSenGreaterThan());
HBufC8* endBody = HBufC8::NewLC(KSenSoapEnvelopeBodyQName().Length()+
KSenLessThanSlash().Length()+
KSenGreaterThan().Length());
TPtr8 endBodyPtr = endBody->Des();
endBodyPtr.Append(KSenLessThanSlash());
endBodyPtr.Append(KSenSoapEnvelopeBodyQName());
endBodyPtr.Append(KSenGreaterThan());
if( SenXmlUtils::StartsWith(*pBody, *startBody) )
{
temp.Delete( 0,startBody->Length() );
}
if( SenXmlUtils::EndsWith(*pTemp, *endBody) )
{
temp.Delete( pTemp->Length()-endBody->Length(),endBody->Length() );
}
CleanupStack::PopAndDestroy(endBody);
CleanupStack::PopAndDestroy(startBody);
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"Re-submitting the request");
//clear Id
retVal = SubmitL(*pTemp,
pConsumer->TransportProperties(*relatesTo),
*pConsumer, aResponse);
//retVal = SubmitL(*pTemp, KNullDesC8, *pConsumer, aResponse);
CleanupStack::PopAndDestroy(pTemp);
return retVal;
}
}
}
// In any other case, it is mean that we can not handle error, we can not
// replace with new response.
// This is a fault which WS* cannot handle
// or ESenReAuthAndResendNeeded which is not supported in SYNC internal mode.
// In other words, wst:RenewNeeded is not supported when it coems from STS.
// It is only supported when it comes from WebService, bit such scenario
// use only ASYNC HandleError
CSenSoapFault* pDetached = apSOAPMessage->DetachFaultL();
CleanupStack::PopAndDestroy( apSOAPMessage ); // de-alloc msg after detach!
TBool completeServerMessages(EFalse);
HasFacetL(KCompleteMessagesFacet, completeServerMessages);
if( pDetached )
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"Detached a SOAP fault");
CleanupStack::PushL(pDetached);
// Response contains only soapfault in case no completeServerMessages facet
// otherwise it should be left empty
// aResponse is updated only when detached soap fault is required.
if(completeServerMessages == EFalse)
{
aResponse = pDetached->AsXmlL();
}
CleanupStack::PopAndDestroy(pDetached);
return KErrSenSoapFault; // this is 2nd OK return code!
}
else
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"- No SOAP fault was received. Returning KErrNotFound");
return KErrNotFound;
}
}
else // apSOAPMessage == NULL
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"- Fatal(!): CWSStarServiceSession::HandleErrorL - apSOAPMessage == NULL!. Returning KErrNotFound.");
return KErrNotFound;
}
}
void CWSStarServiceSession::ReattachCredentialsL()
{
TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel, _L8(" -Entering ReattachCredentialsL iStatus : %d"), iStatus));
TInt retValue = TryToSearchValidCredentialL();
TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel, _L8(" -ReattachCredentialsL retValue : %d"), retValue));
if(retValue != KErrNone)
{
iValidUntil.Set(_L("19000101:")); // way back in history: January 1st 1900
iStatus = ComputeStatusL();
}
TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel, _L8(" -Leaving ReattachCredentialsL iStatus : %d"), iStatus));
}
// ASYNC
TInt CWSStarServiceSession::HandleSoapFaultL( CSenSoapMessage* apSOAPMessage,
const TInt aErrorCode, // should be KErrSenSoapFault..
const TInt aTxnId,
MSenRemoteServiceConsumer& aConsumer,
MSenProperties* aResponseTransportProperties )
{
TInt err(KErrNone);
CSLOG_L(aConsumer.ConnectionId() ,KMinLogLevel ,"CWSStarServiceSession::HandleErrorL(CSenSoapMessage&)");
if( apSOAPMessage )
{
CleanupStack::PushL(apSOAPMessage);
TInt answer = CanHandleErrorL();
if (answer)
{
aConsumer.HandleErrorL(NULL, answer, aTxnId, aResponseTransportProperties);
}
else
{
TBool hasFacet = EFalse;
TInt err1 = HasFacetL(KCompleteMessagesFacet, hasFacet);
HBufC8* pAsXml = NULL;
if (hasFacet && (err1 == KErrNone))
{
CSLOG_L(aConsumer.ConnectionId() ,KNormalLogLevel ,"Full a SOAP fault");
pAsXml = apSOAPMessage->AsXmlL();
}
else
{
CSenSoapFault* pDetached = apSOAPMessage->DetachFaultL();
if(pDetached)
{
CSLOG_L(aConsumer.ConnectionId() ,KMinLogLevel ,"Detached a SOAP fault");
CleanupStack::PushL(pDetached);
// pass KErrSenSoapFault // which is 2nd "OK" return code!
pAsXml = pDetached->AsXmlL();
CleanupStack::PopAndDestroy(pDetached);
}
}
if(pAsXml)
{
aConsumer.HandleErrorL(pAsXml, KErrSenSoapFault, aTxnId, aResponseTransportProperties);
err = KErrNone;
}
else
{
CSLOG_L(aConsumer.ConnectionId() ,KMinLogLevel ,"No SOAP fault was received.");
aConsumer.HandleErrorL(NULL, aErrorCode, aTxnId, aResponseTransportProperties);
err = KErrSenInternal; // pass on the orig error code(?)
}
}
CleanupStack::PopAndDestroy(apSOAPMessage);
}
else
{
CSLOG_L(aConsumer.ConnectionId() ,KMinLogLevel ,"Fatal(!): CWSStarServiceSession::HandleSoapFaultL - apSoapMessage arg is NULL.");
/*TInt retVal =*/ aConsumer.HandleErrorL(NULL, aErrorCode, aTxnId, aResponseTransportProperties);
err = KErrSenInternal;
}
return err;
}
TInt CWSStarServiceSession::CanHandleErrorL()
{
TInt answer(KErrNone);
//if failedAuthentication (SCT is now switched to MT, therefore we have to resend
const TInt* retryAfter = iSessionContext->GetIntL(WSStarContextKeys::KRetryAfter());
//othar case is simple retry after from service
if (!retryAfter)
retryAfter = iInContext->GetIntL(WSStarContextKeys::KRetryAfter());
const TDesC8* redirect = iInContext->GetDesC8L(WSStarContextKeys::KRedirect());
const TBool* renewNeeded = NULL;
if (iSessionContext)
{
renewNeeded = iSessionContext->GetIntL(WSStarContextKeys::KReAuthNeeded());
}
//temporary code, becouse its server proces, we have to leave immediatlly
//retry in milisecunds
if (retryAfter &&
*retryAfter <= WSStarSession::KMaxTimeForRetry*1000 &&
*retryAfter >= KErrNone &&
iRetryCounter < WSStarSession::KCounterMax)
{
TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel, _L8("CWSStarServiceSession::CanHandleErrorL - RETRY request with delay = %d"), *retryAfter));
RTimer timer; // The synchronous timer
TRequestStatus timerStatus; // associated with timer
timer.CreateLocal(); // Always created for this thread.
timer.After(timerStatus,*retryAfter*1000);//in microseconds
User::WaitForRequest(timerStatus);
timer.Close();
iRetryCounter++;
answer = KErrSenResendRequired;
}
else if((renewNeeded && *renewNeeded &&
iRenewCounter < WSStarSession::KCounterMax)
)
{
TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel, _L8("CWSStarServiceSession::CanHandleErrorL - RENEW request (new ticket is needed) iRenewCounter = [%d]"), iRenewCounter)) ;
iRenewCounter++;
answer = KErrSenReinitRequired;
}
else if (redirect &&
iRedirectCounter< WSStarSession::KCounterMax)
{
iRedirectCounter++;
this->SetEndPointL(*redirect);
TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel, _L8("CWSStarServiceSession::CanHandleErrorL - REDIRECT request iRenewCounter = [%d]"), iRedirectCounter) );
answer = KErrSenResendRequired;
}
else
{
iRetryCounter = 0;
iRenewCounter = 0;
iRedirectCounter =0;
answer = KErrNone;
}
return answer;
}
TBool CWSStarServiceSession::Matches(MSenServiceDescription& aPattern)
{
TBool matches = CSenWebServiceSession::Matches(aPattern);
if (!matches) return EFalse;
/*HBufC8* patternClusterValue = NULL;
TPtrC8 clusterFacetName(WSStarSession::KClusterLocalName);
aPattern.FacetValue(clusterFacetName, patternClusterValue);
CleanupStack::PushL(patternClusterValue);
HBufC8* thisClusterValue = NULL;
this->FacetValue(clusterFacetName, thisClusterValue);
CleanupStack::PushL(thisClusterValue);
if (!(thisClusterValue &&
patternClusterValue &&
*thisClusterValue == *patternClusterValue))
{
matches = EFalse;
}
CleanupStack::PopAndDestroy(thisClusterValue);
CleanupStack::PopAndDestroy(patternClusterValue);*/
MSenElement& xmlPatternAsElement = ((CSenWSDescription&)aPattern).AsElement();
// MSenElement* pElement = xmlPatternAsElement.Element(WSStarSession::KProviderIdElementLocalName);
MSenElement* pElement = xmlPatternAsElement.Element( KSenIdpProviderIdLocalname );
//MSenElement* pElement =
// xmlPatternAsElement.Element(WSStarSession::KProviderIdElementLocalName);
if(pElement)
{
TPtrC8 patternProviderID = pElement->Content();
TPtrC8 thisProviderID = ProviderID();
if(patternProviderID.Length()>0)
{
if(!(thisProviderID.Length()>0 && patternProviderID == thisProviderID))
{
return EFalse;
}
}
}
if (aPattern.DescriptionClassType() == MSenServiceDescription::EWSDescription)
{
TPtrC8 patternTransportCue = ((CSenWSDescription&)aPattern).TransportCue();
if (patternTransportCue.Length() > 0)
{
if(!iTransportCue || (patternTransportCue != *iTransportCue))
{
return EFalse;
}
}
}
// for now the only interesting facet is the messageThread facet
// if this session uses messageThreads it should not match any
// description, as it essentially makes the session unique
// (unless nobody is using this session).
if (iMessageThread && HasConsumer())
{
// a new session is needed in any case
matches = EFalse;
}
else
{
TBool hasFacet;
TRAPD(leaveCode, aPattern.HasFacetL(KMessageThread, hasFacet));
if (leaveCode != KErrNone) return EFalse;
if (hasFacet)
{
if (matches && !HasConsumer()) matches = ETrue;
else matches = EFalse;
}
}
return matches;
}
TInt CWSStarServiceSession::ScoreMatchL(MSenServiceDescription& aPattern)
{
TInt score = CSenWebServiceSession::ScoreMatchL(aPattern);
MSenElement& xmlPatternAsElement = ((CSenWSDescription&)aPattern).AsElement();
// MSenElement* pElement = xmlPatternAsElement.Element(WSStarSession::KProviderIdElementLocalName);
MSenElement* pElement = xmlPatternAsElement.Element(KSenIdpProviderIdLocalname);
// MSenElement* pElement =
// xmlPatternAsElement.Element(WSStarSession::KProviderIdElementLocalName);
if(pElement)
{
TPtrC8 patternProviderID = pElement->Content();
TPtrC8 thisProviderID = ProviderID();
if(patternProviderID.Length()>0)
{
if ( thisProviderID.Length()>0 && patternProviderID == thisProviderID )
{
score++;
}
}
}
if (aPattern.DescriptionClassType() == MSenServiceDescription::EWSDescription)
{
TPtrC8 patternTransportCue = ((CSenWSDescription&)aPattern).TransportCue();
if (patternTransportCue.Length() > 0)
{
if ( iTransportCue && (patternTransportCue == *iTransportCue) )
{
score++;
}
}
}
return score;
}
void CWSStarServiceSession::StartTransaction()
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::StartTransaction()");
iMessageThread = ETrue;
}
void CWSStarServiceSession::TransactionCompleted()
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::TransactionCompleted()");
delete ipReceivedMessageIdInTrans;
ipReceivedMessageIdInTrans = NULL;
iMessageThread = EFalse;
}
TInt CWSStarServiceSession::SetTransportPropertiesL(const TDesC8& aProperties,
MSenRemoteServiceConsumer& aConsumer)
{
if(iTransProp)
{
delete iTransProp;
iTransProp = NULL;
}
iTransProp = HBufC8::NewL(aProperties.Length());
TPtr8 ptr = iTransProp->Des();
ptr.Append(aProperties);
CWSStarSessionConsumer* pConsumer = NULL;
//senderID is internal id of consumer
TInt error = SessionConsumerL(aConsumer.Id(), pConsumer);
if (!error && pConsumer)
{
MSenTransport& tp = pConsumer->TransportL();
HBufC8* transProp = ApplyTransportPropertiesL(aProperties);
CleanupStack::PushL(transProp);
tp.SetPropertiesL(*transProp, MSenLayeredProperties::ESenTransportLayer, &aConsumer);
CleanupStack::PopAndDestroy(transProp);
}
return KErrNone;
}
HBufC8* CWSStarServiceSession::ApplyTransportPropertiesL(const TDesC8& aTransportProperties)
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::ApplyTransportPropertiesL():");
TLSLOG_ALL(KSenCoreServiceManagerLogChannelBase , KMaxLogLevel,(aTransportProperties));
HBufC8* result = NULL;
CSenXmlReader* reader = XmlReader();
TInt error(KErrNone);
TPtrC8 value;
CSenVtcpTransportProperties* vtcpTransProp = NULL;
if (aTransportProperties.Length() <= KSenXmlPropertiesLocalname().Length()*2
+ KSenLessThanSlash().Length()
+ KSenLessThan().Length()
+ KSenGreaterThan().Length()*2)
{
if (iTransProp && iTransProp->Length())
{
vtcpTransProp = CSenVtcpTransportProperties::NewLC(*iTransProp, *reader);
}
else
{
vtcpTransProp = CSenVtcpTransportProperties::NewLC();
}
}
else
{
vtcpTransProp = CSenVtcpTransportProperties::NewLC(aTransportProperties, *reader);
if (iTransProp)
{
//1 merge session and message layer transport properties
CSenVtcpTransportProperties* conVtcpTransProp = CSenVtcpTransportProperties::NewLC(*iTransProp, *reader);
//download folder
if (vtcpTransProp->DownloadFolderL(value) == KErrNotFound)
{
if (conVtcpTransProp->DownloadFolderL(value) != KErrNotFound)
{
vtcpTransProp->SetDownloadFolderL(value);
}
}
//device id
if (vtcpTransProp->DeviceIDL(value) == KErrNotFound)
{
if (conVtcpTransProp->DeviceIDL(value) != KErrNotFound)
{
vtcpTransProp->SetDeviceIDL(value);
}
}
if (vtcpTransProp->ProxyHostL(value) == KErrNotFound)
{
if (conVtcpTransProp->ProxyHostL(value) != KErrNotFound)
{
vtcpTransProp->SetProxyHostL(value);
}
}
if (vtcpTransProp->MwsNamespaceL(value) == KErrNotFound)
{
if (conVtcpTransProp->MwsNamespaceL(value) != KErrNotFound)
{
vtcpTransProp->SetMwsNamespaceL(value);
}
}
TBool boolValue;
if (vtcpTransProp->ConnectionBoundL(boolValue) == KErrNotFound)
{
if (conVtcpTransProp->ConnectionBoundL(boolValue) != KErrNotFound)
{
vtcpTransProp->SetConnectionBoundL(boolValue);
}
}
if (vtcpTransProp->OnewayMessageOnOffL(boolValue) == KErrNotFound)
{
if (conVtcpTransProp->OnewayMessageOnOffL(boolValue) != KErrNotFound)
{
vtcpTransProp->SetOnewayMessageOnOffL(boolValue);
}
}
if (vtcpTransProp->BoolPropertyL(KSenIAPDoNotPrompt, boolValue) == KErrNotFound)
{
if (conVtcpTransProp->BoolPropertyL(KSenIAPDoNotPrompt, boolValue) != KErrNotFound)
{
vtcpTransProp->SetBoolPropertyL(KSenIAPDoNotPrompt, boolValue);
}
}
TInt intvalue;
if (vtcpTransProp->ConnectionTimeOutL(intvalue) == KErrNotFound)
{
if (conVtcpTransProp->ConnectionTimeOutL(intvalue) != KErrNotFound)
{
vtcpTransProp->SetConnectionTimeOutL(intvalue);
}
}
if (vtcpTransProp->DeviceLCIDL(value) == KErrNotFound)
{
if (conVtcpTransProp->DeviceLCIDL(value) != KErrNotFound)
{
vtcpTransProp->SetDeviceLCIDL(value);
}
}
if (vtcpTransProp->DeviceLCIDL(value) == KErrNotFound)
{
if (conVtcpTransProp->DeviceLCIDL(value) != KErrNotFound)
{
vtcpTransProp->SetDeviceLCIDL(value);
}
}
if (vtcpTransProp->UserAgentL(value) == KErrNotFound)
{
if (conVtcpTransProp->UserAgentL(value) != KErrNotFound)
{
vtcpTransProp->SetUserAgentL(value);
}
}
TUint32 uint32value;
if (vtcpTransProp->IapIdL(uint32value) == KErrNotFound)
{
if (conVtcpTransProp->IapIdL(uint32value) != KErrNotFound)
{
vtcpTransProp->SetIapIdL(uint32value);
}
}
if (vtcpTransProp->HeartbeatL(intvalue) == KErrNotFound)
{
if (conVtcpTransProp->HeartbeatL(intvalue) != KErrNotFound)
{
vtcpTransProp->SetHeartbeatL(intvalue);
}
}
if (vtcpTransProp->MaxTimeToLiveL(intvalue) == KErrNotFound)
{
if (conVtcpTransProp->MaxTimeToLiveL(intvalue) != KErrNotFound)
{
vtcpTransProp->SetMaxTimeToLiveL(intvalue);
}
}
if (vtcpTransProp->MinTimeToLiveL(intvalue) == KErrNotFound)
{
if (conVtcpTransProp->MinTimeToLiveL(intvalue) != KErrNotFound)
{
vtcpTransProp->SetMinTimeToLiveL(intvalue);
}
}
CleanupStack::PopAndDestroy(conVtcpTransProp);
}
}
error = vtcpTransProp->DeviceIDL(value);
if (error || !value.Length())
{
value.Set(KNullDesC8());
error = ((CWSStarPlugin&)iFramework).DeviceId(value);
if (!error)
{
vtcpTransProp->SetDeviceIDL(value);
}
}
if (iOutContext)
{
if (value.Length())//value of device Id
{
TPtrC8 endpoint = Contract();
TInt pos = endpoint.LocateReverse(TChar('/'));
if (pos!=KErrNotFound)
{
TPtrC8 serviceName = endpoint.Mid(pos);
HBufC8* deviceId = HBufC8::NewLC(value.Length()+serviceName.Length());
TPtr8 deviceIdDes = deviceId->Des();
deviceIdDes.Append(value);
deviceIdDes.Append(serviceName);
iOutContext->Update(WSStarContextKeys::KReplyToDeviceAddress, *deviceId);
CleanupStack::PopAndDestroy(deviceId);
}
else
{
iOutContext->Update(WSStarContextKeys::KReplyToDeviceAddress, value);
}
}
error = vtcpTransProp->ProxyHostL(value);
if (!error)
{
iOutContext->Update(WSStarContextKeys::KReplyTo, value);
}
#ifdef RD_SEN_VTCP_SUPPORT
//Proxy url CR
error = vtcpTransProp->PropertyL(KSenConnectionProxyUrl,value);
if (!error)
{
iOutContext->Update(WSStarContextKeys::KReplyTo, value);
}
#endif//RD_SEN_VTCP_SUPPORT
error = vtcpTransProp->MwsNamespaceL(value);
if (!error)
{
iOutContext->Update(WSStarContextKeys::KMwsNamespace, value);
}
error = vtcpTransProp->SoapActionL(value);
if (!error)
{
_LIT8(KQuote, "\"");
HBufC8* pTemp = HBufC8::NewLC(value.Length());
TPtr8 temp = pTemp->Des();
temp.Append(value);
if(SenXmlUtils::StartsWith(value, KQuote))
{
temp.Delete(0,KQuote().Length());
}
if(SenXmlUtils::EndsWith(*pTemp, KQuote))
{
temp.Delete(pTemp->Length()-1,KQuote().Length());
}
iOutContext->Update(WSStarContextKeys::KAction, *pTemp);
CleanupStack::PopAndDestroy(pTemp);
}
//some GUI clients need messageId in GUI level :( and has control logic realted to messageId
error = vtcpTransProp->PropertyL( KSenClientGeneratedMessageId, value );
if (!error && iOutContext)
{
iOutContext->Update(WSStarContextKeys::KMessageID, value);
}
}
HBufC8* updatedTP = vtcpTransProp->AsUtf8LC();
CSenHttpTransportProperties* httpTransProp = NULL;
if (!updatedTP->Length())
{
httpTransProp = CSenHttpTransportProperties::NewLC();
}
else
{
httpTransProp = CSenHttpTransportProperties::NewLC(*updatedTP, *reader);
}
const TInt* soapVer = iSessionContext->GetIntL(WSStarContextKeys::KSoapVersion);
error = httpTransProp->SoapActionL(value);
if (!error && soapVer)
{
httpTransProp->ApplyBindingL((TSOAPVersion)*soapVer);
}
result = httpTransProp->AsUtf8L();
CleanupStack::PopAndDestroy(httpTransProp);
CleanupStack::PopAndDestroy(updatedTP);
CleanupStack::PopAndDestroy(vtcpTransProp);
return result;
}
TInt CWSStarServiceSession::SendL( const TDesC8& aMessage,
const TDesC8& aTransportProperties,
MSenRemoteServiceConsumer& aConsumer,
TInt& aTxnId,
HBufC8*& aRevalidationError )
{
CSLOG_L(aConsumer.ConnectionId() ,KMinLogLevel ,"CWSStarServiceSession::SendL(TDesC8&, ...)");
TInt retVal(KErrNone);
if ( AmIHostletSession() )
{
CSLOG_L(aConsumer.ConnectionId() ,KMinLogLevel ,"- This is a session for a hostlet.");
retVal = CSenWebServiceSession::SendL( aMessage, aTransportProperties, aConsumer, aTxnId, aRevalidationError );
CSLOG_FORMAT((aConsumer.ConnectionId(), KNormalLogLevel , _L8("- Return value from CSenWebServiceSession::SendL: %d"), retVal ));
CSLOG_FORMAT((aConsumer.ConnectionId(), KNormalLogLevel , _L8("- Transaction ID from transport: %d"), aTxnId ));
}
else
{
CSLOG_L(aConsumer.ConnectionId() ,KMinLogLevel ,"- This is a session for a consumer.");
PrepareOutCtxL(aTransportProperties);
FindAndShareSCTL();
VerifyPermissionL();
//we still have to check if validUntil is not expired.
retVal = RevalidateMobileTicketIfExpiredL( aRevalidationError ); // RefreshMTL
iSessionContext->Update(WSStarContextKeys::KOnlySharing, ETrue);
//retVal = RefreshMTL( aRevalidationError );
#ifdef _SENDEBUG
if( aRevalidationError )
{
CSLOG_L(aConsumer.ConnectionId() ,KMinLogLevel ,"- SOAP Fault / error from re-validation:");
CSLOG_ALL(aConsumer.ConnectionId() ,KMinLogLevel ,( *aRevalidationError ));
}
#endif // _SENDEBUG
if( retVal == KErrNone )
{
delete aRevalidationError; // should ALWAYS be null in here (as retval from RevalidateMobileTicketIfExpiredL was KErrNone!) //(as retval from RefreshMT was KErrNone!)
aRevalidationError = NULL;
HBufC8* transProp = ApplyTransportPropertiesL(aTransportProperties);
CleanupStack::PushL(transProp);
retVal = CSenWebServiceSession::SendL( aMessage, *transProp, aConsumer, aTxnId, aRevalidationError );
CleanupStack::PopAndDestroy(transProp);
}
//else { // if RevalidateMobileTicketIfExpiredL method provided such // } // return error code and aRevalidationError, if RefreshMT method provided such // }
}
return retVal;
}
TInt CWSStarServiceSession::SubmitL( const TDesC8& aMessage,
const TDesC8& aTransportProperties,
MSenRemoteServiceConsumer& aConsumer,
HBufC8*& aResponse )
{
CSLOG_L(aConsumer.ConnectionId() ,KMinLogLevel ,"CWSStarServiceSession::SubmitL(TDesC8&, ...)");
TInt retVal(KErrNone);
if (!AmIHostletSession())
{
PrepareOutCtxL(aTransportProperties);
HBufC8* transProp = ApplyTransportPropertiesL(aTransportProperties);
CleanupStack::PushL(transProp);
retVal = CSenWebServiceSession::SubmitL(aMessage, *transProp, aConsumer, aResponse);
CleanupStack::PopAndDestroy(transProp);
if (retVal == KErrNone)
{
iSubmitState = WSStarSession::KSubmitStateOK;
}
//becouse of lack phase (dispatch to proprr consumer).
//It is SUBMIT nature, only used internally between Client and STS
//we have to make validation here
CWSStarSessionConsumer* consumer = NULL;
if (iInContext)
{
SessionConsumerL(iInContext, consumer);
if (!(consumer && consumer->Id() == aConsumer.Id()))
{
retVal = KErrSenBrokenSoapEnvelope;
}
}
}
return retVal;
}
TInt CWSStarServiceSession::SubmitSoapL( const TDesC8& aSoapMessage,
const TDesC8& aTransportProperties,
MSenRemoteServiceConsumer& aConsumer,
HBufC8*& aResponse )
{
CSLOG_L(aConsumer.ConnectionId() ,KMinLogLevel ,"CWSStarServiceSession::SubmitSoapL(TDesC8& ...)");
TInt retVal(KErrNone);
if (!AmIHostletSession())
{
PrepareOutCtxL(aTransportProperties);
CSenSoapMessage* message = NULL;
HBufC8* body = NULL;
CreateAndParseSoapMessageL(aSoapMessage, message, body);
CleanupStack::PushL(body);
// message ownership transfered to MessageForSendingL
HBufC8* transProp = ApplyTransportPropertiesL(aTransportProperties);
CleanupStack::PushL(transProp);
retVal = MessageForSendingL(*body,aConsumer.Id(),message);
CleanupStack::PushL(message);
HBufC8* pMsg = message->AsXmlL();
CleanupStack::PushL(pMsg);
if (retVal == KErrNone)
{
retVal = CSenWebServiceSession::SubmitSoapL(*pMsg, *transProp, aConsumer, aResponse);
}
CleanupStack::PopAndDestroy(pMsg);
CleanupStack::PopAndDestroy(message);
CleanupStack::PopAndDestroy(transProp);
CleanupStack::PopAndDestroy(body);
if (retVal == KErrNone)
{
iSubmitState = WSStarSession::KSubmitStateOK;
}
//becouse of lack phase (dispatch to proprr consumer).
//It is SUBMIT nature, only used internally between Client and STS
//we have to make validation here
CWSStarSessionConsumer* consumer = NULL;
if (iInContext)
{
SessionConsumerL(iInContext, consumer);
}
if (!(consumer && consumer->Id() == aConsumer.Id()))
{
retVal = KErrSenBrokenSoapEnvelope;
}
}
return retVal;
}
TInt CWSStarServiceSession::SendSoapL( const TDesC8& aSoapMessage,
const TDesC8& aTransportProperties,
MSenRemoteServiceConsumer& aConsumer,
TInt& aTxnId,
HBufC8*& aRevalidationError )
{
CSLOG_L(aConsumer.ConnectionId() ,KMinLogLevel ,"CWSStarServiceSession::SubmitSoapL(TDesC8& ...)");
TInt retVal(KErrNone);
if ( !AmIHostletSession() ) // no support for SendSoapL in hostlet sessions
{
PrepareOutCtxL(aTransportProperties);
FindAndShareSCTL();
VerifyPermissionL();
// We still have to check if validUntil is not expired.
retVal = RevalidateMobileTicketIfExpiredL( aRevalidationError ); // RefreshMTL
iSessionContext->Update(WSStarContextKeys::KOnlySharing, ETrue);
//retVal = RefreshMTL( aRevalidationError );
#ifdef _SENDEBUG
if( aRevalidationError )
{
CSLOG_L(aConsumer.ConnectionId() ,KMinLogLevel ,"- SOAP Fault / error from re-validation:");
CSLOG_ALL(aConsumer.ConnectionId() ,KMinLogLevel ,( *aRevalidationError ));
}
#endif // _SENDEBUG
if (retVal == KErrNone)
{
CSenSoapMessage* message = NULL;
HBufC8* body = NULL;
CreateAndParseSoapMessageL(aSoapMessage, message, body);
CleanupStack::PushL(body);
// message ownership transfered to MessageForSendingL
HBufC8* transProp = ApplyTransportPropertiesL(aTransportProperties);
CleanupStack::PushL(transProp);
retVal = MessageForSendingL(*body,aConsumer.Id(),message);
CleanupStack::PushL(message);
HBufC8* pMsg = message->AsXmlL();
CleanupStack::PushL(pMsg);
ParseToSoapMessage2L( *pMsg,aConsumer,aTxnId );
//wslog FILELOGALL(_L("WsLog"), _L("last_req.xml"), pMsg->Des());
if (retVal == KErrNone)
{
delete aRevalidationError; // should ALWAYS be null in here (as retval from RevalidateMobileTicketIfExpiredL was KErrNone!)// RefreshMT was KErrNone!)
aRevalidationError = NULL;
retVal = CSenWebServiceSession::SendSoapL( *pMsg, *transProp, aConsumer, aTxnId, aRevalidationError );
}
CleanupStack::PopAndDestroy(pMsg);
CleanupStack::PopAndDestroy(message);
CleanupStack::PopAndDestroy(transProp);
CleanupStack::PopAndDestroy(body);
}
//else { // re-validation failed, return an error and aRevalidationError descriptor }
}
return retVal;
}
void CWSStarServiceSession::CreateAndParseSoapMessageL(const TDesC8& aSoapMessage, CSenSoapMessage*& aMessage, HBufC8*& aBody)
{
CSenXmlReader* reader = XmlReader();
aMessage = CSenSoapMessage::NewL();
aMessage->SetReader(*reader);
aMessage->BuildFrom(aSoapMessage);
const TDesC8& uri = aMessage->NsUri();
TInt version;
if (uri == KSenSoapEnvelopeXmlns)
{
version = ESOAP11;
}
else
{
version = ESOAP12;
}
if (iOutContext)
{
iSessionContext->Update(WSStarContextKeys::KSoapVersion,version);
}
CSenElement& bodyEl = aMessage->BodyL();
HBufC8* bodyXml = bodyEl.AsXmlL();
CleanupStack::PushL(bodyXml);
TInt length = bodyXml->Length();
CleanupStack::PopAndDestroy(bodyXml);
aBody = HBufC8::NewLC(length);
RPointerArray<CSenElement>& elements = bodyEl.ElementsL();
TPtr8 body = aBody->Des();
for (TInt i=0;i<elements.Count();i++)
{
CSenElement* element = elements[i];
HBufC8* elXml = element->AsXmlL();
CleanupStack::PushL(elXml);
body.Append(*elXml);
CleanupStack::PopAndDestroy(elXml);
}
CleanupStack::Pop(aBody);
}
TBool CWSStarServiceSession::IsExpiredL()
{
CSenServiceSession::SetStatusL();
return (CSenServiceSession::StatusL() == KSenConnectionStatusExpired);
}
void CWSStarServiceSession::SetSessionContext(CWSStarSessionContext* aContext)
{
delete iSessionContext;
iSessionContext = aContext;
}
CWSStarSessionContext* CWSStarServiceSession::SessionContext()
{
return iSessionContext;
}
void CWSStarServiceSession::ClearCredentialL()
{
// Before removing the credential, checkt that
// iCredentialPtr.Credential() != NULL
if ( HasSecurity() ) // this performs the NULL check for credential
{
// Remove Invalid Credential from Credentials DB
TInt credentialId = iCredentialPtr.Credential()->IdentifierL().IdL(); //codescannerwarnings
((MSenServiceManager&)iFramework.Manager()).RemoveCredentialL(credentialId); //codescannerwarnings
}
// Remove Credential usage from Session
SetSecurityL(KNullDesC8);
iValidUntil.Set(_L("18000101:"));
}
TInt CWSStarServiceSession::InitializeFromL( MSenServiceDescription& aDescription,
CWSStarPolicyHandler* aPolicyHandler )
{
CSenWebServiceSession::SetSecurityL(KNullDesC8);
iValidUntil.Set(_L("19000101:"));//from SetSecurityL()moved to here, because ID-WSF doesn't need
aDescription.HasFacetL(KMessageThread,iMessageThread);
TDescriptionClassType classType = aDescription.DescriptionClassType();
if( classType == MSenServiceDescription::EWSDescription
||
classType == MSenServiceDescription::EWSPattern
||
classType == MSenServiceDescription::EIdentityProvider
)
{
MSenElement& xmlSdAsElement = (
(CSenWSDescription*)&aDescription)->AsElement();
MSenElement* pElement = xmlSdAsElement.Element(KSenIdpProviderIdLocalname);
//MSenElement* pElement =
// xmlSdAsElement.Element(WSStarSession::KProviderIdElementLocalName);
delete iProviderID;
iProviderID = NULL;
if(pElement)
{
iProviderID = pElement->Content().AllocL();
}
else
{
CSenIdentityProvider* provider = ((CWSStarPlugin&)iFramework).
Manager().IdentityProviderL(aDescription);
if (provider)
{
iProviderID = provider->ProviderID().AllocL();
}
}
pElement = xmlSdAsElement.Element(WSStarSession::KTrustAnchorElementLocalName);
if(pElement)
{
delete iTrustAnchor;
iTrustAnchor = NULL;
iTrustAnchor = pElement->Content().AllocL();
}
CSenXmlReader* reader = XmlReader();
if (!iSessionContext)
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::InitializeFromL");
iSessionContext = CWSStarSessionContext::NewL(reader, &aDescription, aPolicyHandler);
pElement = xmlSdAsElement.Element(WSStarSession::KSTRLocalName);
if(pElement)
{
CSenElement* pNestedElement = pElement->Child(0);//assumption STR always has wsse:SecurityTokenReference
if (pNestedElement)
{
HBufC8* content = pNestedElement->AsXmlL();
CleanupStack::PushL(content);
if (content)
{
User::LeaveIfError(iSessionContext->Add(WSStarContextKeys::KSTR, *content));
}
CleanupStack::PopAndDestroy(content);
}
}
//calling higher class load such things like iClientServerInterval
CSenWebServiceSession::InitializeFromL(aDescription);
if ( StatusL() != KSenConnectionStatusReady )
{
// Try to search Credential directly from CredentialManager
// if Connection/Credential is not ready
if ( TryToSearchValidCredentialL() == KErrNone ) //codescannerwarnings
{
SetStatusL();
}
}
if ( !iCredentialPtr.Credential() )
{
pElement = xmlSdAsElement.Element(WSStarSession::KPOPBase64LocalName);
if(pElement)
{
User::LeaveIfError(iSessionContext->Add(WSStarContextKeys::KPOPBase64, pElement->Content()));
}
pElement = xmlSdAsElement.Element(WSStarSession::KTokenType);
if(pElement)
{
User::LeaveIfError(iSessionContext->Add(WSStarContextKeys::KTokenType, pElement->Content()));
}
pElement = xmlSdAsElement.Element(WSStarSession::KBinaryTypeLocalName);
if(pElement)
{
User::LeaveIfError(iSessionContext->Add(WSStarContextKeys::KBinaryType, pElement->Content()));
}
pElement = xmlSdAsElement.Element(WSStarSession::KCreatedLocalName);
if(pElement)
{
User::LeaveIfError(iSessionContext->Add(WSStarContextKeys::KTimestampCreated, pElement->Content()));
}
pElement = xmlSdAsElement.Element(WSStarSession::KPhoneTimeWhenMTResolvedLocalName);
if(pElement)
{
User::LeaveIfError(iSessionContext->Add(WSStarContextKeys::KPhoneTimeWhenMTResolved, pElement->Content()));
}
}
AddSecurityTokenToContextL();
ActiveTicketObserverL();
}
}
else
{
CSenWebServiceSession::InitializeFromL(aDescription);
}
return KErrNone;
}
void CWSStarServiceSession::AddSecurityTokenToContextL()
{
if ( HasSecurity() )
{
CSenCredentialProperties& properties = iCredentialPtr.Credential()->PropertiesL(); //codescannerwarnings
TInt retVal;
TPtrC8 value;
if ( iSessionContext )
{
retVal = properties.PropertyL(WSStarSession::KPOPBase64LocalName, value);
if ( retVal == KErrNone )
{
User::LeaveIfError(iSessionContext->Add(WSStarContextKeys::KPOPBase64, value));
}
retVal = properties.PropertyL(WSStarSession::KTokenType, value);
if ( retVal == KErrNone )
{
User::LeaveIfError(iSessionContext->Add(WSStarContextKeys::KTokenType, value));
}
retVal = properties.PropertyL(WSStarSession::KBinaryTypeLocalName, value);
if ( retVal == KErrNone )
{
User::LeaveIfError(iSessionContext->Add(WSStarContextKeys::KBinaryType, value));
}
retVal = properties.PropertyL(WSStarSession::KCreatedLocalName, value);
if ( retVal == KErrNone )
{
User::LeaveIfError(iSessionContext->Add(WSStarContextKeys::KTimestampCreated, value));
}
retVal = properties.PropertyL(WSStarSession::KPhoneTimeWhenMTResolvedLocalName, value);
if ( retVal == KErrNone )
{
User::LeaveIfError(iSessionContext->Add(WSStarContextKeys::KPhoneTimeWhenMTResolved, value));
}
HBufC8* pSecurity = SecurityL();
if (pSecurity)
{
CleanupStack::PushL(pSecurity);
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::InitializeFromL - adding token to ctx");
retVal = properties.PropertyL(WSStarSession::KTokenType, value);
if ( retVal != KErrNone)
{
value.Set(KNullDesC8);
}
HBufC8* binarySecurityToken =
SenCryptoUtils::CreateEncodedBinarySecretL(*pSecurity, value);
CleanupStack::PopAndDestroy(pSecurity);
CleanupStack::PushL(binarySecurityToken);
User::LeaveIfError(iSessionContext->Add(
WSStarContextKeys::KSecurityToken,
*binarySecurityToken));
User::LeaveIfError(iSessionContext->Add(
WSStarContextKeys::KSecurityTokenBackup,
*binarySecurityToken));
CleanupStack::PopAndDestroy(binarySecurityToken);
TBuf8<SenDateUtils::KXmlDateTimeMaxLength> ts;
SenDateUtils::ToXmlDateTimeUtf82L(ts, iValidUntil);
User::LeaveIfError(iSessionContext->Add(WSStarContextKeys::KTimestampExpires, ts));
}
}
}
}
void CWSStarServiceSession::WriteExtensionsAsXMLToL(RWriteStream& aWriteStream)
{
CSenWebServiceSession::WriteExtensionsAsXMLToL(aWriteStream);
if(iProviderID)
{
aWriteStream.WriteL(WSStarSession::KProviderIDTag);
aWriteStream.WriteL(*iProviderID);
aWriteStream.WriteL(WSStarSession::KProviderIDEndTag);
}
if(iTrustAnchor)
{
aWriteStream.WriteL(WSStarSession::KTrustAnchorTag);
aWriteStream.WriteL(*iTrustAnchor);
aWriteStream.WriteL(WSStarSession::KTrustAnchorEndTag);
}
if(iClientServerInterval.Int64() != 0)
{
aWriteStream.WriteL(WSStarSession::KServiceInterval);
TBuf8<64> buf;
buf.AppendNum(iClientServerInterval.Int64());
aWriteStream.WriteL(buf);
aWriteStream.WriteL(WSStarSession::KServiceIntervalEnd);
}
if (iSessionContext)
{
if ( iCredentialPtr.Credential() )
{/*
CSenCredentialProperties& properties = iCredentialPtr.Credential()->Properties();
const TDesC8* pValue = iSessionContext->GetDesC8L(WSStarContextKeys::KPOPBase64);
if ( pValue )
{
properties.SetPropertyL(WSStarSession::KPOPBase64LocalName(), *pValue);
}
pValue = iSessionContext->GetDesC8L(WSStarContextKeys::KTokenType);
if ( pValue )
{
properties.SetPropertyL(WSStarSession::KTokenType(), *pValue);
}
pValue = iSessionContext->GetDesC8L(WSStarContextKeys::KBinaryType);
if ( pValue )
{
properties.SetPropertyL(WSStarSession::KBinaryTypeLocalName(), *pValue);
}
pValue = iSessionContext->GetDesC8L(WSStarContextKeys::KSTR);
if ( pValue )
{
properties.SetPropertyL(WSStarSession::KSTRLocalName(), *pValue);
}
pValue = iSessionContext->GetDesC8L(WSStarContextKeys::KTimestampCreated);
if ( pValue )
{
properties.SetPropertyL(WSStarSession::KCreatedLocalName(), *pValue);
}
pValue = iSessionContext->GetDesC8L(WSStarContextKeys::KPhoneTimeWhenMTResolved);
if ( pValue )
{
properties.SetPropertyL(WSStarSession::KPhoneTimeWhenMTResolvedLocalName(), *pValue);
}*/
}
else
{
const TDesC8* value = iSessionContext->GetDesC8L(WSStarContextKeys::KPOPBase64);
if(value)
{
aWriteStream.WriteL(WSStarSession::KPOPBase64Tag);
aWriteStream.WriteL(*value);
aWriteStream.WriteL(WSStarSession::KPOPBase64EndTag);
}
value = iSessionContext->GetDesC8L(WSStarContextKeys::KTokenType);
if(value)
{
aWriteStream.WriteL(WSStarSession::KTokenTypeTag);
aWriteStream.WriteL(*value);
aWriteStream.WriteL(WSStarSession::KTokenTypeEndTag);
}
value = iSessionContext->GetDesC8L(WSStarContextKeys::KBinaryType);
if(value)
{
aWriteStream.WriteL(WSStarSession::KBinaryTypeTag);
aWriteStream.WriteL(*value);
aWriteStream.WriteL(WSStarSession::KBinaryTypeEndTag);
}
value = iSessionContext->GetDesC8L(WSStarContextKeys::KSTR);
if(value)
{
aWriteStream.WriteL(WSStarSession::KSTRTag);
aWriteStream.WriteL(*value);
aWriteStream.WriteL(WSStarSession::KSTREndTag);
}
value = iSessionContext->GetDesC8L(WSStarContextKeys::KTimestampCreated);
if(value)
{
aWriteStream.WriteL(WSStarSession::KCreatedTag);
aWriteStream.WriteL(*value);
aWriteStream.WriteL(WSStarSession::KCreatedEndTag);
}
value = iSessionContext->GetDesC8L(WSStarContextKeys::KPhoneTimeWhenMTResolved);
if(value)
{
aWriteStream.WriteL(WSStarSession::KPhoneTimeWhenMTResolvedTag);
aWriteStream.WriteL(*value);
aWriteStream.WriteL(WSStarSession::KPhoneTimeWhenMTResolvedEndTag);
}
}
}
}
TPtrC8 CWSStarServiceSession::ProviderID()
{
if(iProviderID)
return *iProviderID;
else
return KNullDesC8();
}
void CWSStarServiceSession::SetTrustAnchorL(const TDesC8& aURI)
{
delete iTrustAnchor;
iTrustAnchor = NULL;
iTrustAnchor = aURI.AllocL();
}
TPtrC8 CWSStarServiceSession::TrustAnchor()
{
if(iTrustAnchor)
return *iTrustAnchor;
else
return KNullDesC8();
}
TInt CWSStarServiceSession::ComputeStatusL()
{
TInt retVal = CSenServiceSession::ComputeStatusL();
TTime createTime;
//we copy logic from CSenWebServiceSession and add :1) IProviderID condition
if ((retVal == KSenConnectionStatusReady) && iProviderID)
{
TTime now;
//we dont base of Mobile Time
//now.UniversalTime();
// now for us is passportTime + X (x = interval time = now - MTObtainedTime)
// Following check is needed, so that *primary* search for credential properties
// is performed from the credential (first), context search is secondary
// (in practice, compute status call is always performed when we have
// credential so this code is always executed). Requirement for this code:
// => This code is needed, when MT of this session has been expired, but a valid Module Test exists in DB
// In WebServiceSession layer, there is a search (find) logic, looking for valid Module Tests, after which
// the super class will call ComputeStatusL() [since WSS cannot know SIF spesific rules for validity].
if ( HasSecurity() )
{
CSenCredentialProperties& properties = iCredentialPtr.Credential()->PropertiesL(); //codescannerwarnings
TPtrC8 createdValue;
TInt retVal = properties.PropertyL(WSStarSession::KCreatedLocalName, createdValue);
if ( retVal == KErrNone )
{
TTime clientTime;
TTime mtTime;
TPtrC8 mtTimetd;
retVal = properties.PropertyL(WSStarSession::KPhoneTimeWhenMTResolvedLocalName, mtTimetd);
if ( retVal == KErrNone )
{
mtTime = SenDateUtils::FromXmlDateTimeL(mtTimetd);
clientTime.UniversalTime();
if (clientTime != Time::NullTTime())
{
TTimeIntervalMicroSeconds diff = clientTime.MicroSecondsFrom(mtTime);
createTime = SenDateUtils::FromXmlDateTimeL(createdValue);
now = createTime;
if (diff > 0)
{
now += diff;
}
}
}
}
else
{
now.UniversalTime();
}
}
else if ( iSessionContext )
{
const TDesC8* createdValue = iSessionContext->GetDesC8L(WSStarContextKeys::KTimestampCreated);
if (createdValue)
{
TTime clientTime;
TTime mtTime;
const TDesC8* mtTimetd = iSessionContext->GetDesC8L(WSStarContextKeys::KPhoneTimeWhenMTResolved);
if (mtTimetd)
{
mtTime = SenDateUtils::FromXmlDateTimeL(*mtTimetd);
clientTime.UniversalTime();
if (clientTime != Time::NullTTime())
{
TTimeIntervalMicroSeconds diff = clientTime.MicroSecondsFrom(mtTime);
createTime = SenDateUtils::FromXmlDateTimeL(*createdValue);
now = createTime;
if (diff > 0)
{
now += diff;
}
}
}
}
else
{
now.UniversalTime();
}
}
else
{
//for passport session, (internal session)
//We wil base on Device time
now.UniversalTime();
}
#ifdef _SENDEBUG
TBuf8<SenDateUtils::KXmlDateTimeMaxLength> timeStr;
TRAPD(leaveCode, SenDateUtils::ToXmlDateTimeUtf82L(timeStr, now);)
TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KNormalLogLevel, _L8("CWSStarServiceSession::computeStatus - now =: %S"), &timeStr));
TRAP(leaveCode, SenDateUtils::ToXmlDateTimeUtf82L(timeStr, createTime);)
TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KNormalLogLevel, _L8("CWSStarServiceSession::computeStatus - created =: %S"), &timeStr));
TRAP(leaveCode, SenDateUtils::ToXmlDateTimeUtf82L(timeStr, iValidUntil);)
TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KNormalLogLevel, _L8("CWSStarServiceSession::computeStatus - iValidUntil =: %S"), &timeStr));
#endif
//HC !!!!!!!!!!!! very tricky things. Microsoft ticket always expires after 10hours event timestamps says sth different
/// therefore we simulate 14 hours (so one day ticket 24H -14 gives 10 magic hours)
/*const TInt KMSUndocumentedMinutes = 60*14; //nice for testing is 60*23+56
TTimeIntervalMinutes ticketWindow;
iValidUntil.MinutesFrom(createTime, ticketWindow);
if (ticketWindow > TTimeIntervalMinutes(KMSUndocumentedMinutes))
{
LOG_WRITE((_L("CWSStarServiceSession::computeStatus ticket window is ok")));
now = now + TTimeIntervalMinutes(KMSUndocumentedMinutes);
}
else
{
LOG_WRITE((_L("CWSStarServiceSession::computeStatus ticket window is too short to cut sth")));
}
#ifdef _SENDEBUG
TRAP(leaveCode, SenDateUtils::ToXmlDateTimeUtf8L(timeStr, now);)
if (!leaveCode)
{
LOG_WRITEFORMAT((_L8("CWSStarServiceSession::computeStatus + fake MS 10Hours- now =: %S"), &timeStr));
}
#endif
*/
//include also margin (3 minutes)
if (iValidUntil != Time::NullTTime() &&
now > (iValidUntil - TTimeIntervalMinutes(KClockSlipMinutes)))
//||
//(iValidUntil == Time::NullTTime() &&
//!HasSecurity()))
{
TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,(_L("CWSStarServiceSession::Credential is expired.")));
retVal = KSenConnectionStatusExpired;
}
else
{
TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,(_L("CWSStarServiceSession::Credential is ok.")));
}
}
return retVal;
}
void CWSStarServiceSession::PrepareOutCtxL(const TDesC8& aTransportProperties)
{
iClientTime.UniversalTime();
CSenXmlReader* reader = XmlReader();
if (iOutContext)
{
delete iOutContext;
iOutContext = NULL;
}
iOutContext = CWSStarMessageContext::NewL(SenContext::EOutgoing, reader);
if (aTransportProperties != KNullDesC8)
{
iOutContext->Add(WSStarContextKeys::KWSStarTranspProp,
aTransportProperties);
}
}
// This method IS USED only by ASYNC methods (serving session SendL invokations
// from 3rd party developer via SC) but NOT by sync methods (like internal consumers)
TInt CWSStarServiceSession::RevalidateMobileTicketIfExpiredL( HBufC8*& aErrorMessage ) // RefreshMTL
//TInt CWSStarServiceSession::RefreshMTL( HBufC8*& aErrorMessage )
{
TInt result(KErrNone);
if (IsExpiredL())
{
//we need revalidate
TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,(_L("CWSStarServiceSession::RevalidateMobileTicketIfExpiredL - revalidation is required.")));
//LOG_WRITE((_L("CWSStarServiceSession::RefreshMT - we have to refresh")));
result = ((CWSStarPlugin&)iFramework).ProcessOutboundValidationL( *this, this, aErrorMessage );
if ( result == KErrNone )
{
// validation succeeded => serialize this session (and its credentials immediately)
iFramework.Manager().SaveL( *this ); // this will currently *also* serialize associated credential (new/updated MT)
}
return result;
}
//LOG_WRITE((_L("CWSStarServiceSession::RefreshMT - ticket still valid")));
TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,(_L("CWSStarServiceSession::RevalidateMobileTicketIfExpiredL - ticket is still valid.")));
return KErrNone;
}
TBool CWSStarServiceSession::HasSuperClass( TDescriptionClassType aType )
{
if( aType == MSenServiceDescription::EWebServiceSession ) // direct superclass!
{
// If asked type is the know *direct* father/mother, return true:
return ETrue;
}
else
{
// Otherwise, ask from superclass (chain, recursively)
return CSenWebServiceSession::HasSuperClass( aType );
}
}
TInt CWSStarServiceSession::ShareTokenWithL( CWSStarServiceSession* aWSStarSessionDst,
TBool& aMTwasReplaceBySCT,
TBool aSeekSCT )
{
TInt error(KErrNone);
if (aSeekSCT)
{
const TInt* isR = NULL;
isR = iSessionContext->GetIntL(WSStarContextKeys::KMTIsReplacedBySCT);
if (!isR || (isR && *isR == FALSE)) return KErrNotFound;
}
if ( !HasSecurity() )//if not MT than SCT for sure doesnt exist
{
return KErrNotFound;
}
//share MT (only not expired), otherway it is sensless
//dont call SetStatus/IsExpired becouse it will infornm consumer/Core about chnge.
//Session will not be able to revalidate by itself in next sending
if (ComputeStatusL() != KSenConnectionStatusExpired)
{
/*#ifdef _SENDEBUG
_LIT8(KCredsLogLine, "Token sharing FROM (%S) TO (%S)");
CREDLOG_FORMAT((KSenCredsLogChannel, KSenCredsLogLevelNormal, KCredsLogLine, &Endpoint(), &(aWSStarSessionDst->Endpoint())));
#endif */
//share possible SCT are already in ctx
error = iSessionContext->ShareTokenWithL(
aWSStarSessionDst->SessionContext(), aMTwasReplaceBySCT);
//HBufC8* pSecurity = SecurityL();
//CleanupStack::PushL(pSecurity);
//aWSStarSessionDst->AddCredentialL(*pSecurity, iValidUntil);//this also recalculate state
aWSStarSessionDst->AddCredentialL(iCredentialPtr, iValidUntil);//this also recalculate state
//CleanupStack::PopAndDestroy(pSecurity);
return error;
}
else
{
return KErrNotFound;
}
}
void CWSStarServiceSession::AddCredentialL( const TDesC8& aSecurity, TTime aValidUntil )
{
iValidUntil = aValidUntil;
SetSecurityL(aSecurity);
SetStatusL();
}
void CWSStarServiceSession::AddCredentialL(RSenCredentialPtr aCredentialPtr, TTime aValidUntil)
{
iValidUntil = aValidUntil;
SetCredentialPtrL(aCredentialPtr); // Share same Credential between multiple Sessions //codescannerwarnings
SetStatusL();
}
TBool CWSStarServiceSession::AmIHostletSession()
{
if(iTransportCue && (KSenTransportCueHostletConnection() == *iTransportCue))
{
return ETrue;
}
return EFalse;
}
void CWSStarServiceSession::FindAndShareSCTL()
{
if (!iProviderID)
{
return;
}
//1) check if we have already SCT
const TInt* isR = iSessionContext->GetIntL(WSStarContextKeys::KMTIsReplacedBySCT);
if (isR && *isR == TRUE) return;//SCT already exist so we dont have to share
//2) real sharing
HBufC8* clusterUsed = CWSStarPolicy::GetPolicyValueL(WSPolicy::KIssuedToken, WSPolicy::KRPSCluster, (CWSStarPlugin&)iFramework, this);
TInt retVal(KErrNone);
//its mean - if our provider uses cluster template,
//we can SCT form other msn services which use same provider ID
if (clusterUsed)
{
RPointerArray<CSenWSDescription> msnSDs;
CleanupClosePushL(msnSDs);
CSenWSPattern* pattern = CSenWSPattern::NewLC();
//select * from session_of_SD where session is (ws* framework, and has same provideId)
//here we assume that provider use cluster template
pattern->SetFrameworkIdL(KDefaultWSStarFrameworkID);
pattern->AsElement().AddElementL(KSenIdpProviderIdLocalname).SetContentL(*iProviderID);
//pattern->AsElement().AddElementL(WSStarSession::KProviderIdElementLocalName).SetContentL(*iProviderID);
//seeking
CWSStarServiceSession* msnSession = NULL;
TRAPD(leaveError, retVal = ((CWSStarPlugin&)iFramework).Manager().ServiceDescriptionsL(msnSDs, *pattern));
// Becouse they are registered without framework Id (DAO keep sessions, but in client case only SD -> see registering STSClient, DSClient..)
// SD matches only by enpoint and contract
if(!retVal && !leaveError)
{
TInt count = msnSDs.Count();
TBool pMTwasReplaceBySCT = EFalse;
//if MT has been shared already than it happened during validation
// now we just looking for SCT.
//usecase:
// -----SC1::new
// -----SC2:new (MT sharing inside trusat client
// -----SC1::send (SCT is only inside SC1)
// -----SC2::send (now we can share SCT)
TBool seekOnlySCT = ETrue;
for(TInt i = 0; i < msnSDs.Count(); i++)
{
//all sessions (so in practice we have also access to SCT, not only MT),
// to eliminate client, just for case we check type
TDescriptionClassType dt = msnSDs[i]->DescriptionClassType();
if (dt == MSenServiceDescription::EWSStarServiceSession)
{
msnSession = (CWSStarServiceSession*)msnSDs[i];
TRAPD(err, retVal = msnSession->ShareTokenWithL(
this, pMTwasReplaceBySCT,
seekOnlySCT));
if ((retVal == KErrNone) && (err == KErrNone))
{
if (pMTwasReplaceBySCT)
{
break;
}
}
}
}
}
CleanupStack::PopAndDestroy(2, &msnSDs);
}
delete clusterUsed;
}
TInt CWSStarServiceSession::UpdatePolicyL( CWSStarPolicyHandler* aPolicyHandler, MSenServiceDescription* aSD )
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::UpdatePolicyL");
CWSStarSessionContext* pCtx = SessionContext();
if( !pCtx )
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KNormalLogLevel,"CWSStarServiceSession::UpdatePolicyL: - Attempting to create new session context");
// In the future => session context exists BEFORE the session even has been created(!)
CSenXmlReader* reader = XmlReader();
iSessionContext = CWSStarSessionContext::NewL(reader, aSD, aPolicyHandler);
pCtx = SessionContext();
if( !pCtx )
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::UpdatePolicyL: - FATAL: unable to create new session context(!).");
return KErrSenInternal; // very unlikely oom case (that did not leave!) / construction of ctx oddly failed
}
}
return pCtx->UpdatePolicyL(aPolicyHandler, aSD);
}
void CWSStarServiceSession::ParseToSoapMessage2L( const TDesC8& aSoapMessage, MSenRemoteServiceConsumer& aConsumer, TInt& aTxnId )
{
TInt ctxLookupErr(KErrNone);
CSenSoapMessageDom2* soapMessage2 = NULL;
MSenMessageContext* pCtx = aConsumer.MessageContextByTxnIdL( aTxnId, ctxLookupErr );
if( ctxLookupErr == KErrNone && pCtx )
{
soapMessage2 = (CSenSoapMessageDom2*)pCtx->MessageL(); //codescannerwarnigs
}
if (!soapMessage2)
{
return;
}
CSenSoapMessageDom2* newMessage2 = CSenSoapMessageDom2::NewLC();
CSenParser* parser = CSenParser::NewLC();
parser->EnableFeature(EReportNamespaceMapping);
parser->ParseL(aSoapMessage, *newMessage2);
CleanupStack::PopAndDestroy(parser);
_LIT8(KCidPrefix, "cid:*");
RArray<TXmlEngElement> binaryElements;
RXmlEngNodeList<TXmlEngAttr> attrArray;
CleanupClosePushL(binaryElements);
TXmlEngElement rootElement = newMessage2->AsElementL();
TInt countEl = ListBinaryElementsL(binaryElements,rootElement);
if (countEl == 0)
{
CleanupStack::PopAndDestroy(&binaryElements);
CleanupStack::Pop(newMessage2);
pCtx->SetMessage(newMessage2,ETrue);
return;
}
CSLOG_FORMAT((aConsumer.ConnectionId(), KMinLogLevel , _L8("- Count of <xop:Include elements> in DOM tree: %d"), countEl));
TXmlEngAttr attr;
TPtrC8 cid;
RSenDocument document = newMessage2->AsDocumentL();
RSenDocument doc = soapMessage2->AsDocumentL();
RArray<TXmlEngDataContainer> dataContainerArray;
CleanupClosePushL(dataContainerArray);
doc.GetDataContainerList(dataContainerArray);
TInt countDC(dataContainerArray.Count());
TXmlEngElement element;
if ( countEl > 0 && countDC > 0 )
{
for ( TInt i = 0; i < countEl; i++ )
{
element = binaryElements[i];
element.GetAttributes(attrArray);
while ( attrArray.HasNext() )
{
attr = attrArray.Next();
TPtrC8 value = attr.Value();
TInt position = value.Match(KCidPrefix);
if ( position < 0 )
{
position = 0;
}
cid.Set(value.Mid( position + KCidPrefix().Size() - 1)); // minus star character (*)
if ( cid.Length() > 0 )
{
break;
}
}
attrArray.Close();
for ( TInt j = 0; j < countDC; j++ )
{
TXmlEngDataContainer dataContainer = dataContainerArray[j];
if ( dataContainer.Cid() == cid )
{
if ( dataContainer.NodeType() == TXmlEngNode::EChunkContainer)
{
TXmlEngChunkContainer binData =
document.CreateChunkContainerL(
dataContainer.Cid(),
dataContainer.AsChunkContainer().Chunk(),
dataContainer.AsChunkContainer().ChunkOffset(),
dataContainer.AsChunkContainer().Size() );
element.ReplaceWith(binData);
}
else if ( dataContainer.NodeType() == TXmlEngNode::EFileContainer)
{
TXmlEngFileContainer binData =
document.CreateFileContainerL(
dataContainer.Cid(),
dataContainer.AsFileContainer().File() );
element.ReplaceWith(binData);
}
break;
}
}
}
}
CleanupStack::PopAndDestroy(2, &binaryElements);
CleanupStack::Pop(newMessage2);
pCtx->SetMessage(newMessage2,ETrue);
}
TInt CWSStarServiceSession::ListBinaryElementsL( RArray<TXmlEngElement>& aElementArray,
TXmlEngElement& aElement )
{
// TLSLOG_L(KSenCoreServiceManagerLogChannelBase, KMinLogLevel,"CWSStarServiceSession::ListBinaryElementsL"); // logged *way* TOO often! => commented out
_LIT8(KInclude, "Include");
_LIT8(KXopIncludeUri, "http://www.w3.org/2004/08/xop/include");
TInt count(0);
RXmlEngNodeList<TXmlEngElement> list;
CleanupClosePushL(list);
aElement.GetChildElements(list);
TInt c = list.Count();
#ifdef _SENDEBUG
TPtrC8 root = aElement.Name();
TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KNormalLogLevel, _L8("- Processing element: '%S', num of child elements: %d"), &root, c));
TPtrC8 content = aElement.Text();
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMaxLogLevel,"---- Content START ----");
TLSLOG_ALL(KSenCoreServiceManagerLogChannelBase , KMaxLogLevel,(content));
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMaxLogLevel,"---- Content END ----");
#endif // _SENDEBUG
while ( list.HasNext() )
{
TXmlEngElement element = list.Next();
TPtrC8 tag = element.Name();
TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMaxLogLevel, _L8("- child: '%S'"), &tag));
if ( tag == KInclude )
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMaxLogLevel,"- <xop:Include> element found.");
if ( element.NamespaceUri() == KXopIncludeUri )
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMaxLogLevel,"- namespace == http://www.w3.org/2004/08/xop/include");
aElementArray.AppendL(element);
count = count + 1;
}
}
count = count + ListBinaryElementsL(aElementArray, element);
}
CleanupStack::PopAndDestroy(&list);
return count;
}
void CWSStarServiceSession::FillCredentialIdentifierL(CSenCredentialIdentifier& aIdentifier)
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::FillCredentialIdentifierL:");
CSenWebServiceSession::FillCredentialIdentifierL(aIdentifier);
//_LIT8(KProviderIdElementLocalName, "ProviderID");
//aIdentifier.SetPropertyL(KProviderIdElementLocalName, ProviderID());
TPtrC8 providerId = ProviderID();
aIdentifier.SetPropertyL(KSenIdpProviderIdLocalname, providerId);
// Add information about the account that is priviledged to consume this credential
// (a) find matching IDP description (which represents the account / userinfo)
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"- About to call LookupIdentityProviderL");
CSenIdentityProvider* pIdentityProvider = LookupIdentityProviderL();
// CSenIdentityProvider* pIdentityProvider = NULL;
// if ( providerId != KNullDesC8 )
// {
// LOG_WRITEFORMAT((_L8("- Searching for IdentityProvider using ProviderId : %S"), &providerId));
// CSenWSDescription* pIdpPattern = CSenWSDescription::NewLC();
// pIdpPattern->SetEndPointL(providerId);
// pIdentityProvider = iFramework.Manager().IdentityProviderL(*pIdpPattern);
// CleanupStack::PopAndDestroy(pIdpPattern);
// }
if ( pIdentityProvider )
{
TPtrC8 username = pIdentityProvider->UserName();
if( username.Length() > 0 )
{
aIdentifier.SetPropertyL(KSenIdpAuthzIDLocalname, username);
}
TPtrC8 password = pIdentityProvider->Password();
if( password.Length() > 0 )
{
aIdentifier.SetPropertyL(KSenIdpPasswordLocalname, password);
}
}
}
void CWSStarServiceSession::VerifyPermissionL()
{
if( HasSecurity() )
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::VerifyPermissionL:");
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"- Making call to LookupIdentityProviderL");
CSenIdentityProvider* pProvider = LookupIdentityProviderL();
if ( pProvider )
{
CSenCredentialIdentifier& identifier = iCredentialPtr.Credential()->IdentifierL();
TPtrC8 username; // that was used to acquire this credential
TInt retVal = identifier.PropertyL(KSenIdpAuthzIDLocalname, username);
TPtrC8 password; // that was used to acquire this credential
retVal = identifier.PropertyL(KSenIdpPasswordLocalname, password);
TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMaxLogLevel, _L8("=> Credential properties: username = '%S', password = '%S'"), &username, &password));
TPtrC8 accountUsername = pProvider->UserName();
TPtrC8 accountPassword = pProvider->Password();
TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMaxLogLevel, _L8("=> Candidate IDP details: username = '%S', password = '%S'"), &accountUsername, &accountPassword));
if( ( username.Length() > 0 && username != accountUsername ) ||
( password.Length() > 0 && password != accountPassword ) )
{
// either username or password DOES NOT MATCH (and the mismatching
// one is not zero-length string)
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"-> Will not grant permission to consume current credential,");
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMaxLogLevel," clearing credential & it's properties from context.");
SetSecurityL(KNullDesC8);
ClearCredentialPropertiesFromContext();
}
else
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"--> Permission to consume current credential is granted.");
// => Permission to consume this credential is granted(!)
}
}
else
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"- There is no IDP (account), clearing credential & it's properties from context.");
// It is not possible to consumer WS-* service(s) without IDP (account)
SetSecurityL(KNullDesC8);
ClearCredentialPropertiesFromContext();
}
}
else
{
// If session has no credential (neither MT or SCT), neither should it have any
// related data in context(!)
//--> LOG_WRITE_L("- There is no credential, clearing credential properties from context.");
//--> SetSecurityL(KNullDesC8);
ClearCredentialPropertiesFromContext();
}
}
CSenIdentityProvider* CWSStarServiceSession::LookupIdentityProviderL()
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,"CWSStarServiceSession::LookupIdpL()");
TPtrC8 providerId = ProviderID();
CSenIdentityProvider* pIdentityProvider = NULL;
if ( providerId != KNullDesC8 )
{
TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel, _L8("- Searching for IdentityProvider using ProviderId : %S"), &providerId));
CSenWSDescription* pIdpPattern = CSenWSDescription::NewLC();
pIdpPattern->SetEndPointL(providerId);
pIdentityProvider = iFramework.Manager().IdentityProviderL(*pIdpPattern);
CleanupStack::PopAndDestroy(pIdpPattern);
}
return pIdentityProvider;
}
void CWSStarServiceSession::AddPropertiesFromSessionContextToCredentialL()
{
if (iSessionContext)
{
if ( iCredentialPtr.Credential() )
{
CSenCredentialProperties& properties = iCredentialPtr.Credential()->PropertiesL(); //codescannerwarnings
const TDesC8* pValue = iSessionContext->GetDesC8L(WSStarContextKeys::KPOPBase64);
if ( pValue )
{
properties.SetPropertyL(WSStarSession::KPOPBase64LocalName(), *pValue);
}
pValue = iSessionContext->GetDesC8L(WSStarContextKeys::KTokenType);
if ( pValue )
{
properties.SetPropertyL(WSStarSession::KTokenType(), *pValue);
}
pValue = iSessionContext->GetDesC8L(WSStarContextKeys::KBinaryType);
if ( pValue )
{
properties.SetPropertyL(WSStarSession::KBinaryTypeLocalName(), *pValue);
}
pValue = iSessionContext->GetDesC8L(WSStarContextKeys::KSTR);
if ( pValue )
{
properties.SetPropertyL(WSStarSession::KSTRLocalName(), *pValue);
}
pValue = iSessionContext->GetDesC8L(WSStarContextKeys::KTimestampCreated);
if ( pValue )
{
properties.SetPropertyL(WSStarSession::KCreatedLocalName(), *pValue);
}
pValue = iSessionContext->GetDesC8L(WSStarContextKeys::KPhoneTimeWhenMTResolved);
if ( pValue )
{
properties.SetPropertyL(WSStarSession::KPhoneTimeWhenMTResolvedLocalName(), *pValue);
}
// Now, serialize this session (and all it's updated credentials) into database(s)
iFramework.Manager().SaveL( *this ); // this will currently *also* serialize associated credential (new/updated MT)
}
}
}
TBool CWSStarServiceSession::HasEqualPrimaryKeysL( MSenServiceDescription& aCandidate )
{
TBool retVal(EFalse);
if ( CSenWSDescription::HasEqualPrimaryKeysL(aCandidate) )
{
// Endpoint, Contract and FrameworkID match, all of them.
// Now, in WS-*, also check ProviderID
if (aCandidate.DescriptionClassType() == DescriptionClassType())
{
CWSStarServiceSession& sessionCandidate = (CWSStarServiceSession&)aCandidate;
if (sessionCandidate.ProviderID() == ProviderID())
{
retVal = ETrue;
}
}
}
return retVal;
}
void CWSStarServiceSession::CredentialChanged( TSenCredentialChange aChange,
TAny* apPointer )
{
if ( aChange == MSenCredentialObserver::EDestroyed && iSessionContext )
{
ClearCredentialPropertiesFromContext();
}
CSenWebServiceSession::CredentialChanged( aChange, apPointer );
}
void CWSStarServiceSession::ClearCredentialPropertiesFromContext()
{
if( iSessionContext )
{
iSessionContext->Remove(WSStarContextKeys::KPOPBase64);
iSessionContext->Remove(WSStarContextKeys::KTokenType);
iSessionContext->Remove(WSStarContextKeys::KBinaryType);
iSessionContext->Remove(WSStarContextKeys::KSTR);
iSessionContext->Remove(WSStarContextKeys::KTimestampCreated);
iSessionContext->Remove(WSStarContextKeys::KPhoneTimeWhenMTResolved);
iSessionContext->Remove(WSStarContextKeys::KMTIsReplacedBySCT);
iSessionContext->Remove(WSStarContextKeys::KSecurityToken);
}
//CSenWebServiceSession::CredentialChanged(aChange, apPointer);
}
void CWSStarServiceSession::ActiveTicketObserverL()
{
const TDesC8* createdValue = iSessionContext->GetDesC8L(WSStarContextKeys::KTimestampCreated);
const TDesC8* expiresValue = iSessionContext->GetDesC8L(WSStarContextKeys::KTimestampExpires);
const TDesC8* phoneTimeValue = iSessionContext->GetDesC8L(WSStarContextKeys::KPhoneTimeWhenMTResolved);
TTimeIntervalMinutes margin(KClockSlipMinutes - 1);
if (createdValue && expiresValue && phoneTimeValue)
{
TTime expTime, creTime, phTime, nowTime;
creTime = SenDateUtils::FromXmlDateTimeL(*createdValue);
expTime = SenDateUtils::FromXmlDateTimeL(*expiresValue);
phTime = SenDateUtils::FromXmlDateTimeL(*phoneTimeValue);
creTime += margin;
TTimeIntervalMicroSeconds diff = expTime.MicroSecondsFrom(creTime);
#ifdef _SENDEBUG
TBuf8<64> buf;
buf.Num( diff.Int64() );
TLSLOG_FORMAT(( KSenCoreServiceManagerLogChannelBase, KNormalLogLevel, _L8("CWSStarServiceSession::ActiveTicketObserverL - range %S microsec"), &buf ));
#endif // _SENDEBUG
nowTime.UniversalTime();
if (nowTime != Time::NullTTime())
{
TTimeIntervalMicroSeconds diff2 = nowTime.MicroSecondsFrom( phTime ); // already missed time
#ifdef _SENDEBUG
buf.Num( diff2.Int64() );
TLSLOG_FORMAT(( KSenCoreServiceManagerLogChannelBase , KNormalLogLevel, _L8("CWSStarServiceSession::ActiveTicketObserverL - already pased %S microsec"), &buf ));
#endif // _SENDEBUG
diff = TTimeIntervalMicroSeconds( diff.Int64() - diff2.Int64() ); // Counting the real difference
}
if (diff > 0)
{
iTicketObs->Start( diff );//nowTime + diff);
#ifdef _SENDEBUG
buf.Num(diff.Int64());
TLSLOG_FORMAT(( KSenCoreServiceManagerLogChannelBase, KNormalLogLevel, _L8("CWSStarServiceSession::ActiveTicketObserverL - iTicketObs->Start(%S) microsec"), &buf ));
TBuf8<SenDateUtils::KXmlDateTimeMaxLength> ts;
SenDateUtils::ToXmlDateTimeUtf8L(ts, nowTime + diff);
TLSLOG_FORMAT(( KSenCoreServiceManagerLogChannelBase , KNormalLogLevel, _L8("CWSStarServiceSession::ActiveTicketObserverL - START time %S "), &ts ));
#endif
}
#ifdef _SENDEBUG
else
{
TLSLOG_L(KSenCoreServiceManagerLogChannelBase, KMinLogLevel, "CWSStarServiceSession::ActiveTicketObserverL - SKIP - ticket expired already we don't need to wait");
// ==> Validation phase will soon executed and new timer WILL BE activated
}
#endif
}
}
// End of file