diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/SIPSec/IpSecPlugin/src/CIpSecPolicyHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/SIP/SIPSec/IpSecPlugin/src/CIpSecPolicyHandler.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,379 @@ +// Copyright (c) 2005-2009 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: +// Name : CIpSecPolicyHandler.cpp +// Part of : SIPSec +// Version : SIP/4.0 +// + + + +#include +#include +#include + +#include "CIpSecPolicyHandler.h" +#include "MSipSecPolicyObserver.h" +#include "SipSecIpsecParams.h" + +#ifndef CPPUNIT_TEST +// Comment this definition off, if ipsec is wanted to be used for real +//#define DISABLE_IPSEC_POLICY_USAGE +#endif + +// ---------------------------------------------------------------------------- +// CIpSecPolicyHandler::NewL +// ---------------------------------------------------------------------------- +// +CIpSecPolicyHandler* CIpSecPolicyHandler::NewL( + MSipSecPolicyObserver& aObserver, + RIpsecPolicyServ& aPolicyServ ) + { + CIpSecPolicyHandler* + self = CIpSecPolicyHandler::NewLC( aObserver, aPolicyServ ); + CleanupStack::Pop( self ); + return self; + } + +// ---------------------------------------------------------------------------- +// CIpSecPolicyHandler::NewLC +// ---------------------------------------------------------------------------- +// +CIpSecPolicyHandler* CIpSecPolicyHandler::NewLC( + MSipSecPolicyObserver& aObserver, + RIpsecPolicyServ& aPolicyServ ) + { + CIpSecPolicyHandler* + self = new ( ELeave ) CIpSecPolicyHandler( aObserver, aPolicyServ ); + CleanupStack::PushL( self ); + return self; + } + + +// ---------------------------------------------------------------------------- +// CIpSecPolicyHandler::~CIpSecPolicyHandler +// ---------------------------------------------------------------------------- +// +CIpSecPolicyHandler::~CIpSecPolicyHandler() + { + Cancel(); + delete iPolicyData; + } + +// ---------------------------------------------------------------------------- +// CIpSecPolicyHandler::CreatePolicyL +// ---------------------------------------------------------------------------- +// +void CIpSecPolicyHandler::CreatePolicyL( + const TInetAddr& aLocalAddress, + const TInetAddr& aRemoteAddress, + const TSipSecSaParams& aSaParams ) + { + if ( IsActive() && iHandlerState != EIdle ) + { + User::Leave( KErrInUse ); + } + + HBufC8* localAddr = GetAddrAsTextLC( aLocalAddress ); + TPtr8 plocalAddr( localAddr->Des() ); + HBufC8* remoteAddr = GetAddrAsTextLC( aRemoteAddress ); + TPtr8 premoteAddr( remoteAddr->Des() ); + + HBufC8* mask = 0; + if ( !(aLocalAddress.Address())) + { + _LIT8( KV6Mask, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" ); + mask = KV6Mask().AllocLC(); + } + else + { + _LIT8( KV4Mask, "255.255.255.255" ); + mask = KV4Mask().AllocLC(); + } + TPtr8 pmask( mask->Des() ); + + RemovePolicyData(); + + const TInt KMAxTUint32AsDescLen = 10; + + _LIT8( KPolicyFormat, +"SECURITY_FILE_VERSION: 3\r\n\ +[INFO]\r\n\ +SIP IPSec policies\r\n\ +[POLICY]\r\n\ +sa sip_sas = {\r\n\ +esp\r\n\ +encrypt_alg 11\r\n\ +auth_alg %u\r\n\ +src_specific\r\n\ +local_port_specific\r\n\ +remote_port_specific\r\n\ +}\r\n\ +local %S %S local_port %u remote %S %S remote_port %u = { sip_sas() }\r\n\ +local %S %S local_port %u remote %S %S remote_port %u = { sip_sas() }\r\n\ +local %S %S local_port %u = drop\r\n\ +inbound = {}\r\n\ +outbound = {}\r\n" ); + + iPolicyData = HBufC8::NewL( KPolicyFormat().Length() + + 6 * KMAxTUint32AsDescLen + + 2 * premoteAddr.Length() + + 5 * pmask.Length() + + 3 * plocalAddr.Length() ); + + TPtr8 pdata( iPolicyData->Des() ); + + // Form policy data. Drop policy for the port_us cannot be created + // since it will affect to other SAs using the same protected server port. + // Instead, dropping of packets coming to port_us from incorrect remote + // addresses is handled in ConnectionMgr level. + pdata.AppendFormat( KPolicyFormat, + aSaParams.iAuthAlg, + &plocalAddr, + &pmask, + aSaParams.iPort_us, + &premoteAddr, + &pmask, + aSaParams.iPort_pc, + &plocalAddr, + &pmask, + aSaParams.iPort_uc, + &premoteAddr, + &pmask, + aSaParams.iPort_ps, + &plocalAddr, + &pmask, + aSaParams.iPort_uc ); + + CleanupStack::PopAndDestroy( mask ); + CleanupStack::PopAndDestroy( remoteAddr ); + CleanupStack::PopAndDestroy( localAddr ); + +#ifdef DISABLE_IPSEC_POLICY_USAGE + // Dummy completion of the loading request + iStatus = KRequestPending; + SetActive(); + iHandlerState = ELoading; + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); +#else + // Start loading the policy + iPolicyServ.LoadPolicy( *iPolicyData, iPolicyHandle, iStatus ); + iHandlerState = ELoading; + SetActive(); +#endif + } + +// ---------------------------------------------------------------------------- +// CIpSecPolicyHandler::RemovePolicy +// ---------------------------------------------------------------------------- +// +void CIpSecPolicyHandler::RemovePolicy() + { + // Cancel first outstanding operations + Cancel(); + +#ifdef DISABLE_IPSEC_POLICY_USAGE + // Dummy completion of the unloading request + iStatus = KRequestPending; + SetActive(); + iHandlerState = EUnloading; + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); +#else + // Start unloading + iPolicyServ.UnloadPolicy( iPolicyHandle(), iStatus ); + iHandlerState = EUnloading; + SetActive(); +#endif + } + +// ---------------------------------------------------------------------------- +// CIpSecPolicyHandler::RunL +// ---------------------------------------------------------------------------- +// +void CIpSecPolicyHandler::RunL() + { + TInt err( iStatus.Int() ); + + if ( err != KErrNone ) + { + RemovePolicyData(); + NotifyError( err ); + return; + } + + switch ( iHandlerState ) + { + case ELoading: + { + // Policy data is not needed anymore + RemovePolicyData(); + +#ifdef DISABLE_IPSEC_POLICY_USAGE + // Dummy completion of the activating request + iStatus = KRequestPending; + SetActive(); + iHandlerState = EActivating; + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); +#else + // Start activating the policy + iPolicyServ.ActivatePolicy( iPolicyHandle(), iStatus ); + iHandlerState = EActivating; + SetActive(); +#endif + break; + } + case EActivating: + { + // Inform observer, all done + iHandlerState = EActive; + NotifyActiveL(); + break; + } + case EUnloading: + { + // Inform observer + iHandlerState = EIdle; + NotifyUnload(); + break; + } + default: + { + break; + } + } + } + +// ----------------------------------------------------------------------------- +// CIpSecPolicyHandler::RunError +// ----------------------------------------------------------------------------- +// +TInt CIpSecPolicyHandler::RunError( TInt aError ) + { + if ( aError != KErrNoMemory ) + { + return KErrNone; + } + return aError; + } + +// ---------------------------------------------------------------------------- +// CIpSecPolicyHandler::DoCancel +// ---------------------------------------------------------------------------- +// +void CIpSecPolicyHandler::DoCancel() + { + switch ( iHandlerState ) + { + case ELoading: + { + iPolicyServ.CancelLoad(); + break; + } + case EActivating: + { + iPolicyServ.CancelActivate(); + break; + } + case EUnloading: + { + iPolicyServ.CancelUnload(); + break; + } + default: + { + break; + } + } + } + +// ---------------------------------------------------------------------------- +// CIpSecPolicyHandler::CIpSecPolicyHandler +// ---------------------------------------------------------------------------- +// +CIpSecPolicyHandler::CIpSecPolicyHandler( + MSipSecPolicyObserver& aObserver, + RIpsecPolicyServ& aPolicyServ ) : + CActive( EPriorityStandard ), + iObserver( aObserver ), + iPolicyServ( aPolicyServ ), + iHandlerState( EIdle ) + { + CActiveScheduler::Add( this ); + } + +// ---------------------------------------------------------------------------- +// CIpSecPolicyHandler::GetAddrAsTextLC +// ---------------------------------------------------------------------------- +// +HBufC8* CIpSecPolicyHandler::GetAddrAsTextLC( const TInetAddr& aAddr ) + { + const TInt KMaxInetAddrLen = 256; + TBuf tempAddr; + aAddr.Output( tempAddr ); + + HBufC8* address = HBufC8::NewLC( tempAddr.Length() ); + TPtr8 paddress( address->Des() ); + TInt ret = + CnvUtfConverter::ConvertFromUnicodeToUtf8( paddress, tempAddr ); + + if ( ret > 0 || ret == CCnvCharacterSetConverter::EErrorIllFormedInput ) + { + User::Leave( KErrGeneral ); + } + + return address; + } + +// ---------------------------------------------------------------------------- +// CIpSecPolicyHandler::RemovePolicyData +// ---------------------------------------------------------------------------- +// +void CIpSecPolicyHandler::RemovePolicyData() + { + delete iPolicyData; + iPolicyData = 0; + } + +// ---------------------------------------------------------------------------- +// CIpSecPolicyHandler::NotifyActiveL +// ---------------------------------------------------------------------------- +// +void CIpSecPolicyHandler::NotifyActiveL() + { + iObserver.PolicyActivatedL(); + } + +// ---------------------------------------------------------------------------- +// CIpSecPolicyHandler::NotifyUnload +// ---------------------------------------------------------------------------- +// +void CIpSecPolicyHandler::NotifyUnload() + { + iObserver.PolicyUnloaded(); + } + +// ---------------------------------------------------------------------------- +// CIpSecPolicyHandler::NotifyError +// ---------------------------------------------------------------------------- +// +void CIpSecPolicyHandler::NotifyError( TInt aError ) + { + TPolicyHandlerState oldState = iHandlerState; + iHandlerState = EIdle; + iObserver.PolicyError( oldState, aError ); + } + +// End of File