vpnengine/kmdserver/src/secpolreader.cpp
changeset 0 33413c0669b9
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Security policy module
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <es_sock.h>
       
    20 #include <in_sock.h>
       
    21 #include <networking/ipsecerr.h>
       
    22 #include <vpnlogmessages.rsg>
       
    23 #include "ikedebug.h"
       
    24 #include "kmdeventloggerif.h"
       
    25 #include "secpolpayload.h"
       
    26 
       
    27 // CLASS HEADER
       
    28 #include "secpolreader.h"
       
    29 
       
    30 // ======== LOCAL FUNCTIONS ========
       
    31 
       
    32 #ifdef _DEBUG
       
    33 
       
    34 // ---------------------------------------------------------------------------
       
    35 // Returns error description.
       
    36 // ---------------------------------------------------------------------------
       
    37 //
       
    38 static const TPtrC IpsecError( TInt aReason )
       
    39     {
       
    40     switch ( aReason )
       
    41         {
       
    42         case EIpsec_RMBUF:              return _L("RMBUF operation failed unexcpectedly");
       
    43         //
       
    44         // AH and ESP
       
    45         //
       
    46         case EIpsec_CorruptPacketIn:    return _L("Truncated or corrupt packet or header");
       
    47         case EIpsec_CorruptPacketOut:   return _L("Corrupt packet after IPSEC operations");
       
    48         case EIpsec_EspInboundSA:       return _L("The inbound SA for ESP does not exist");
       
    49         case EIpsec_EspAuthentication:  return _L("Authentication check failed in ESP");
       
    50         case EIpsec_EspAuthAlg:         return _L("Required auth algorithm for ESP not available/installed");
       
    51         case EIpsec_EspEncrAlg:         return _L("Required encrypt algorithm for ESP not available/installed");
       
    52         case EIpsec_AhAuthAlg:          return _L("Required auth algorithm for AH not available/installed");    
       
    53         case EIpsec_AhInboundSA:        return _L("The inbound SA for AH does not exist");
       
    54         case EIpsec_AhIcvLength:        return _L("ICV length in packet does not match algorithm");
       
    55         case EIpsec_AhAuthentication:   return _L("Authentication check failed in AH");
       
    56         case EIpsec_PacketLength:       return _L("Invalid/corrupt length of the packet");
       
    57         case EIpsec_DataAlignment:      return _L("Data not aligned by block size (ESP)");
       
    58         case EIpsec_EspPadByte:         return _L("The ESP pad byte content is invalid");
       
    59         case EIpsec_EspPadLength:       return _L("The ESP pad length is corrupt (probably wrong key)");
       
    60         case EIpsec_ReplayDuplicate:    return _L("Duplicate packet (replay window test)");
       
    61         //
       
    62         // SECPOL
       
    63         //
       
    64         case EIpsec_OutboundNotFound:   return _L("Outbound SA does not exist, ACQUIRE started");
       
    65         case EIpsec_OutboundPending:    return _L("Outbooud SA does not exits, ACQUIRE pending");
       
    66         case EIpsec_NoSelectorMatch:    return _L("None of the policy selectors matched");
       
    67         case EIpsec_MaxTransforms:      return _L("Incoming packet exceed configured max limit of transforms");
       
    68         case EIpsec_TooFewTransforms:   return _L("Policy requires IPSEC, none or too little was present");
       
    69         case EIpsec_TunnelMismatch:     return _L("Tunnelmode does not match the policy");
       
    70         case EIpsec_MismatchedSA:       return _L("Applied SA does not match the policy");
       
    71         case EIpsec_UnrequiredSA:       return _L("Applied SA where policy has none");
       
    72         case EIpsec_TooManyTransforms:  return _L("Incoming packet had more transforms than policy requires");
       
    73         case EIpsec_NoBundle:           return _L("Incoming packet had transforms, but policy doesn't require any");
       
    74         //
       
    75         // IPv6 additions
       
    76         //
       
    77         case EIpsec_AhRMBufSplit:       return _L("Inbound AH processing failed (Memory?)");
       
    78         case EIpsec_AhPacketTooLong:    return _L("Outbound packet would exeed 2**16-1 with AH");
       
    79         case EIpsec_AhSequenceWrap:     return _L("Outbound sequence # wrapped around for this SA");
       
    80         case EIpsec_EspSequenceWrap:    return _L("Outbound sequence # wrapped around for this SA");
       
    81         case EIpsec_EspBadCipherBlockSize:  return _L("Configuration error, cipher block size must be < 256");
       
    82         case EIpsec_AcquireFailed:      return _L("Acquiring SA failed (no SA available or negotiated)");
       
    83         //
       
    84         // Detail reasons for SA not matching the SA spec in the policy
       
    85         // (replace one EIpsec_MismatchedSA with multiple detail errors)
       
    86         //
       
    87         case EIpsec_MismatchedDestination:  return _L("SA destination does not match (internal error?)");
       
    88         case EIpsec_MismatchedType:     return _L("SA Type (AH/ESP) does not match");
       
    89         case EIpsec_MismatchedPFS:      return _L("PFS bit is not same");
       
    90         case EIpsec_MismatchedAuthAlg:  return _L("Auth algorithm doesn't match");
       
    91         case EIpsec_MismatchedEncryptAlg:   return _L("Encrypt algorithm doesn't match");
       
    92         case EIpsec_MismatchReplayWindow:   return _L("ReplayWindow length is shorter than required");
       
    93         case EIpsec_MismatchSource:     return _L("source address does not match");
       
    94         case EIpsec_MismatchProxy:      return _L("proxy address does not match");
       
    95         case EIpsec_MismatchSourcePort: return _L("source port does not match");  
       
    96         case EIpsec_MismatchDestinationPort:return _L("destination port does not match");
       
    97         case EIpsec_MismatchProtocol:   return _L("protocol does not match");
       
    98         case EIpsec_MismatchSourceIdentity: return _L("source identity does not match");
       
    99         case EIpsec_MismatchDestinationIdentity: return _L("destination identity does not match");
       
   100     
       
   101         case EIpsec_BadCipherKey:       return _L("Key in SA is too short (for the algorithm) or is weak");
       
   102         case EIpsec_UnknownCipherNumber: return _L("Attempting to use algorithm number that is not known");
       
   103         case EIpsec_UnknownDigestNumber: return _L("Attempting to use algorithm number that is not known");
       
   104         case EIpsec_UnavailableCipher: return _L("No installed library implements the cipher");
       
   105         case EIpsec_UnavailableDigest: return _L("No installed library implements the digest");
       
   106         //
       
   107         // Temporary place for new errors
       
   108         //
       
   109         case EIpsec_IcmpError:  return _L("An ICMP error report containing AH or ESP (for INET6)");
       
   110         case EIpsec_LostSA:     return _L("An SA has been lost between Apply and Verify, expired? (for SECPOL)");
       
   111         case EIpsec_NoInnerSource: return _L("Cannot find inner-src for outbound packet when tunneling (for SECPOL)");
       
   112         //
       
   113         // Special code for NAT Traversal  
       
   114         //
       
   115         case EIpsec_NotANATTPacket: return _L("UDP packet is NOT a NAT Taversal packet");
       
   116         case EIpsec_FragmentMismatch: return _L("IPSEC on fragment is not same as before, packet dropped");
       
   117     
       
   118         default:
       
   119             return _L("Unknown reason");
       
   120         }
       
   121     }
       
   122 
       
   123 #endif
       
   124 
       
   125 // ======== MEMBER FUNCTIONS ========
       
   126 
       
   127 // ---------------------------------------------------------------------------
       
   128 // Two-phased constructor.
       
   129 // ---------------------------------------------------------------------------
       
   130 //
       
   131 CSecpolReader* CSecpolReader::NewL( MKmdEventLoggerIf& aEventLogger,
       
   132                                     MIkeDebug& aDebug )
       
   133     {
       
   134     CSecpolReader* self = new (ELeave) CSecpolReader( aEventLogger,
       
   135                                                       aDebug );
       
   136     CleanupStack::PushL( self );    
       
   137     self->ConstructL();
       
   138     CleanupStack::Pop( self );
       
   139     return self;
       
   140     }
       
   141 
       
   142 // ---------------------------------------------------------------------------
       
   143 // Destructor.
       
   144 // ---------------------------------------------------------------------------
       
   145 //
       
   146 CSecpolReader::~CSecpolReader()
       
   147     {
       
   148     DEBUG_LOG(_L("CSecpolReader::~CSecpolReader"));
       
   149     Cancel();
       
   150     iSocket.Close();
       
   151     iSocketServer.Close();        
       
   152     }
       
   153 
       
   154 // ---------------------------------------------------------------------------
       
   155 // Constructor.
       
   156 // ---------------------------------------------------------------------------
       
   157 //
       
   158 CSecpolReader::CSecpolReader( MKmdEventLoggerIf& aEventLogger,
       
   159                               MIkeDebug& aDebug )
       
   160 : CActive( EPriorityStandard ),
       
   161   iEventLogger( aEventLogger ),
       
   162   iDebug( aDebug )
       
   163     {
       
   164     CActiveScheduler::Add( this );
       
   165     }
       
   166 
       
   167 // ---------------------------------------------------------------------------
       
   168 // Second phase construction.
       
   169 // ---------------------------------------------------------------------------
       
   170 //
       
   171 void CSecpolReader::ConstructL()
       
   172     {
       
   173     TInetAddr addr;
       
   174     User::LeaveIfError( iSocketServer.Connect() );
       
   175     User::LeaveIfError( iSocket.Open( iSocketServer, _L("secpol6") ) );
       
   176     addr.SetAddress( KInetAddrNone );
       
   177     addr.SetPort( 0 );
       
   178     User::LeaveIfError( iSocket.Bind( addr ) );
       
   179     iSocket.RecvFrom( iMsg, iAddr, 0, iStatus );
       
   180     SetActive();
       
   181     DEBUG_LOG(_L("CSecpolReader::ConstructL - constructed"));
       
   182     }
       
   183 
       
   184 // ---------------------------------------------------------------------------
       
   185 // Returns event logger.
       
   186 // ---------------------------------------------------------------------------
       
   187 //
       
   188 MKmdEventLoggerIf& CSecpolReader::EventLogger()
       
   189     {
       
   190     return iEventLogger;
       
   191     }
       
   192 
       
   193 
       
   194 // ---------------------------------------------------------------------------
       
   195 // From class CActive
       
   196 // Handles completion of asynchronous reading. 
       
   197 // ---------------------------------------------------------------------------
       
   198 //
       
   199 void CSecpolReader::RunL()
       
   200     {        
       
   201 #ifdef _DEBUG
       
   202     TBuf<40> buf;
       
   203     TBuf<1000> str;
       
   204 	TInt protocol = -1;
       
   205 #endif // _DEBUG    
       
   206     TInt  len = 0;
       
   207 	TBool processEvent;
       
   208     TSecpolPayload packet( iMsg.Ptr() );
       
   209     
       
   210     DEBUG_LOG1(_L("Secpol read, status=%d"), iStatus.Int());
       
   211     __ASSERT_DEBUG( iStatus.Int() == KErrNone,
       
   212                     User::Invariant() );
       
   213     if ( iStatus.Int() == KErrNone )
       
   214         {
       
   215         switch ( packet.iIP4->Version() )
       
   216             {
       
   217             case 4:
       
   218     			processEvent = ((THdrIP4 *)packet.iRaw)->IsUnicast();
       
   219     			if ( processEvent )
       
   220     			    {	
       
   221 #ifdef _DEBUG			
       
   222     			    ((THdrIP4 *)packet.iRaw)->Dump( str, iMsg.Length() );
       
   223     			    protocol = packet.iIP4->Protocol();
       
   224 #endif // _DEBUG			   
       
   225     			    len = packet.iIP4->HeaderLength();
       
   226     			    }    
       
   227                     break;
       
   228             case 6:
       
   229     			processEvent = ((THdrIP6 *)packet.iRaw)->IsUnicast();
       
   230     			if ( processEvent )
       
   231     			    {	
       
   232 #ifdef _DEBUG			
       
   233     			    ((THdrIP6 *)packet.iRaw)->Dump( str, iMsg.Length() );
       
   234     			    protocol = packet.iIP6->NextHeader();
       
   235 #endif // _DEBUG			   
       
   236     			    len = packet.iIP6->HeaderLength();
       
   237     			    }    
       
   238                     break;
       
   239             default:
       
   240     			    processEvent = ETrue;
       
   241 #ifdef _DEBUG			
       
   242     			    str.Format( _L("Unknown IP protocol version %d"),
       
   243     			                (TInt)packet.iIP4->Version() );
       
   244 #endif // _DEBUG            
       
   245     			    break;
       
   246             }
       
   247     	
       
   248     	if ( processEvent )
       
   249     	    {		 
       
   250     	    if ( len )
       
   251                {
       
   252                packet.iRaw += len;
       
   253 #ifdef _DEBUG          
       
   254                packet.Dump( str, iMsg.Length()-len, protocol );
       
   255 #endif // _DEBUG          
       
   256                }
       
   257 #ifdef _DEBUG       
       
   258     	    str.Append( _L(" from ") );
       
   259     	    (TInetAddr::Cast(iAddr)).OutputWithScope( buf );
       
   260     	    str.Append( buf );
       
   261     	    str.Append( _L(" because ") );
       
   262     	    str.Append( IpsecError( iAddr.Port() ) );
       
   263     	    str.AppendFormat( _L(" (%d)"), iAddr.Port() );
       
   264     	    DEBUG_LOG(str);
       
   265 #endif // _DEBUG       
       
   266     
       
   267     	    LOG_KMD_EVENT( MKmdEventLoggerIf::KLogWarning,
       
   268     	                   R_VPN_MSG_DATA_DROPPED_DUE_POLICY,
       
   269     	                   (TInt)iAddr.Port(),
       
   270     	                   0,
       
   271     	                   &iAddr );    	        	    
       
   272     	    }
       
   273         }
       
   274         
       
   275     iSocket.RecvFrom( iMsg, iAddr, 0, iStatus );  // start a new read
       
   276     SetActive();
       
   277     }
       
   278 
       
   279 // ---------------------------------------------------------------------------
       
   280 // From class CActive
       
   281 // Handles cancellation of asynchronous reading. 
       
   282 // ---------------------------------------------------------------------------
       
   283 //
       
   284 void CSecpolReader::DoCancel()
       
   285     {
       
   286     iSocket.CancelRecv();
       
   287     }