realtimenetprots/sipfw/SIP/SIPSec/IpSecPlugin/src/CIpSecPolicyHandler.cpp
changeset 0 307788aac0a8
--- /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 <utf.h>
+#include <convutils.h>
+#include <lib_pfkey.h>
+
+#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<KMaxInetAddrLen> 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