networksecurity/ipsec/ipsecpol/src/ipsecpolmanconflict.cpp
changeset 0 af10295192d8
child 6 c64cefac6e99
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // IPSecPolManConflict - IPSec Policy Manager policy conflict checking routines
       
    15 //
       
    16 // Portions Copyright (c) Symbian Software Ltd. 2007.
       
    17 // Portions Copyright (c) Nokia Corporation 2005 - 2006. * Nokia Core OS *
       
    18 // Save as expressly licensed to you by Symbian Software Ltd, all rights reserved.
       
    19 //
       
    20 
       
    21 #include <in_sock.h>
       
    22 
       
    23 #include "ipsecpolmanhandler.h"
       
    24 #include "ipsecpolparser.h"
       
    25 #include "ipsecpolapi.h"
       
    26 
       
    27 //
       
    28 // Calculates and returns the BypassDrop mode of given security policy.
       
    29 // This method gets called whenever a new policy is parsed.
       
    30 //
       
    31 //
       
    32 TInt
       
    33 CIPSecPolicyManagerHandler::CalculatePolicyBypassDropMode(
       
    34     CSecurityPolicy& aSp) const
       
    35     {
       
    36     CSelectorList* list = aSp.SelectorList();
       
    37     TInt count(list->Count());
       
    38     TBool isInboundDropMode(EFalse);
       
    39     TBool isOutboundDropMode(EFalse);
       
    40 
       
    41     // Default mode is 'drop_everything_else' if nothing is specified in the
       
    42     // supplied policy
       
    43     TInt mode(KDropMode);
       
    44 
       
    45     // Iterate through the selector list
       
    46     for (TInt i = 0; i < count; i++)
       
    47         {
       
    48         CPolicySelector* ps = list->At(i);
       
    49 
       
    50         // Check if pure INBOUND with 'bypass_everything_else' action
       
    51         if (ps->iDirection == KPolicySelector_INBOUND
       
    52             && IsBypassEverythingElse(*ps)
       
    53             && !isInboundDropMode)
       
    54             {
       
    55             // Set Inbound bypass mode
       
    56             mode |= KInboundBypass;
       
    57             }
       
    58 
       
    59         // Check if pure INBOUND with 'drop_everything_else' action
       
    60         if (ps->iDirection == KPolicySelector_INBOUND
       
    61             && IsDropEverythingElse(*ps)
       
    62             && !isInboundDropMode)
       
    63             {
       
    64             // Clear Inbound bypass mode if drop requested and set mode to drop
       
    65             // so that if there exist conflicting bypass rule in the selector
       
    66             // list it does not override the drop mode ie. drop mode allways
       
    67             // overrides the bypass mode
       
    68             mode &= ~KInboundBypass;
       
    69             isInboundDropMode = ETrue;
       
    70             }
       
    71 
       
    72         // Check if pure OUTBOUND with 'bypass_everything_else' action
       
    73         if (ps->iDirection == KPolicySelector_OUTBOUND
       
    74             && IsBypassEverythingElse(*ps)
       
    75             && !isOutboundDropMode)
       
    76             {
       
    77             // Set Outbound bypass mode
       
    78             mode |= KOutboundBypass;
       
    79             }
       
    80 
       
    81         // Check if pure OUTBOUND with 'drop_everything_else' action
       
    82         if (ps->iDirection == KPolicySelector_OUTBOUND
       
    83             && IsDropEverythingElse(*ps)
       
    84             && !isOutboundDropMode)
       
    85             {
       
    86             // Clear Outbound bypass mode if drop requested and set mode to drop
       
    87             // so that if there exist conflicting bypass rule in the selector
       
    88             // list it does not override the drop mode ie. drop mode allways
       
    89             // overrides the bypass mode
       
    90             mode &= ~KOutboundBypass;
       
    91             isOutboundDropMode = ETrue;
       
    92             }
       
    93         }
       
    94 
       
    95     return (mode);
       
    96     }
       
    97 
       
    98 //
       
    99 // Determines the BypassDrop mode of combined policy that will be loaded into 
       
   100 // the IPsec protocol component. This function gets called when Activate 
       
   101 // or Unload request is entered.
       
   102 //
       
   103 // The combined policy loaded into the protocol component contains the
       
   104 // 'drop_everything_else' rule if one or more active policies contains
       
   105 // this rule. Otherwise 'bypass_every_else' rule is loaded.
       
   106 //
       
   107 //
       
   108 TBool
       
   109 CIPSecPolicyManagerHandler::CalculateCombinedPolicyBypassDropMode()
       
   110     {
       
   111     // Combined mode is 'bypass_everything_else' by default
       
   112     TInt combinedMode(KInboundBypass | KOutboundBypass);
       
   113 
       
   114     // Iterate through the policy list to determine the combined mode
       
   115     TInt count(iActivePolicyList->Count());
       
   116     for (TInt i = 0; i < count; i++)
       
   117         {
       
   118         TActivePolicyListEntry* entry = iActivePolicyList->At(i);
       
   119 
       
   120         // Check if the policy is activated
       
   121         if (!entry->iActiveState)
       
   122             continue;
       
   123 
       
   124         // Check if active policy contains 'drop_everything_else' rule and
       
   125         // then set combined mode to 'drop' and stop iteration
       
   126         if (entry->iBypassOrDropMode == KDropMode)
       
   127             {
       
   128             combinedMode = KDropMode;
       
   129             break;
       
   130             }
       
   131 
       
   132         // Check if active policy contains 'drop_inbound_everything_else' and
       
   133         // then clear the 'inbound_bypass' flag of the combined mode
       
   134         if (!(entry->iBypassOrDropMode & KInboundBypass))
       
   135             {
       
   136             combinedMode &= ~KInboundBypass;
       
   137             }
       
   138 
       
   139         // Check if active policy contains 'drop_outbound_everything_else' and
       
   140         // then clear the 'outbound_bypass' flag of the combined mode
       
   141         if (!(entry->iBypassOrDropMode & KOutboundBypass))
       
   142             {
       
   143             combinedMode &= ~KOutboundBypass;
       
   144             }
       
   145         }
       
   146 
       
   147     // Save calculated Bypass/Drop mode for later use and return 
       
   148     // TRUE if mode changed. The saved mode is used when loading
       
   149     // the combined policy into IPsec protocol component
       
   150     TBool changed = (iBypassOrDropMode != combinedMode);
       
   151     iBypassOrDropMode = combinedMode;
       
   152     return(changed);
       
   153     }
       
   154 
       
   155 //
       
   156 // This function controls the checking of conflicts relating to the selectors
       
   157 // in the new policy and the policies existing in the Active Policy list.
       
   158 //
       
   159 // There are two main conflict reasons:
       
   160 //  -- Port and protocol parameters are not matching,
       
   161 //  -- Incorrectly overlapping addresses.
       
   162 //
       
   163 // If a conflict is found, the iLastError member is filled with Info
       
   164 // parameter of the old policy.
       
   165 //
       
   166 //
       
   167 void
       
   168 CIPSecPolicyManagerHandler::CheckSelectorConflictsL()
       
   169     {
       
   170     TInt j(0);
       
   171     TInt count(iActivePolicyList->Count());
       
   172 
       
   173     //
       
   174     // If the Active Policy list is empty no checking is done
       
   175     //
       
   176     if (!count)
       
   177         return;
       
   178 
       
   179     //
       
   180     // Take the next policy from the active policy list and parse the
       
   181     // policy. Do the port/protocol conflict tests against the new policy
       
   182     //
       
   183     for (j = 0; j < count; j++)
       
   184         {
       
   185         TakeNextActivePolicyL(j);
       
   186         ConflictTestForPortsAndProtocolL();
       
   187         }
       
   188 
       
   189     //
       
   190     // Take the next policy from the active policy list and parse the
       
   191     // policy. Do the overlapping address conflict tests.
       
   192     //
       
   193     for (j = 0; j < count; j++)
       
   194         {
       
   195         TakeNextActivePolicyL(j);
       
   196 
       
   197         // Set base for the first selector of new policy
       
   198         CSecurityPolicy* sp = iPieceData->Policies();
       
   199         CSelectorList* list = sp->SelectorList();
       
   200         TInt count = list->Count();
       
   201 
       
   202         // Iterate selectors and make comparison if necessary
       
   203         for (TInt i = 0; i < count; i++)
       
   204             {
       
   205             CPolicySelector* ps = list->At(i);
       
   206 
       
   207             // If 'bypass/drop_everything_else' action then skip comparison
       
   208             if (IsBypassEverythingElse(*ps) || IsDropEverythingElse(*ps))
       
   209                 {
       
   210                 continue;
       
   211                 }
       
   212             
       
   213             // Compare selectors. If error found, the called function
       
   214             // calls ErrorHandling and stores the content of Info parameter of
       
   215             // old policy to the iLastError buffer
       
   216             CompareSelectorsL(ps);
       
   217             }
       
   218         }
       
   219     }
       
   220 
       
   221 //
       
   222 // This function takes the next policy from the active policy list,
       
   223 // parses it to object format, and returns the parsed policy data
       
   224 // in iPieceData2 member
       
   225 //
       
   226 //
       
   227 void
       
   228 CIPSecPolicyManagerHandler::TakeNextActivePolicyL(TInt aIndex)
       
   229     {
       
   230     // Release the previous parsed PieceData object
       
   231     delete iPieceData2;
       
   232     iPieceData2 = 0;
       
   233 
       
   234     // Allocate a new PieceData object
       
   235     iPieceData2 = new (ELeave) CIpSecurityPiece;
       
   236     if (!iPieceData2)
       
   237         {
       
   238         ErrorHandlingL(ENoMemory, 0);
       
   239         }
       
   240     iPieceData2->ConstructL();
       
   241 
       
   242     // Take the policy buffer of the next active policy
       
   243     HBufC8* policyHBufC8 = iActivePolicyList->At(aIndex)->iPolicyBuf;
       
   244 
       
   245     // Copy policy to 16bit buffer
       
   246     TPtr8 ptr8 = policyHBufC8->Des();
       
   247     TInt length = ptr8.Length();
       
   248     HBufC *policyDataHBufC16 = HBufC::NewL(length + 1);
       
   249     CleanupStack::PushL(policyDataHBufC16);
       
   250     TPtr ptr(policyDataHBufC16->Des());
       
   251     ptr.FillZ();
       
   252     ptr.Copy(ptr8);
       
   253     ptr.ZeroTerminate();
       
   254 
       
   255     // Parse the policy
       
   256     TIpSecParser parser(ptr);
       
   257     TInt err = parser.ParseAndIgnoreIKEL(iPieceData2);
       
   258     CleanupStack::PopAndDestroy();
       
   259 
       
   260     if (err != KErrNone)
       
   261         {
       
   262         ErrorHandlingL(EParsingError, err);
       
   263         }
       
   264     return;
       
   265     }
       
   266 
       
   267 //
       
   268 // This function checks whether there are conflicts between the new policy
       
   269 // and old policies relating to the ports and protocol parameters
       
   270 // in selectors.
       
   271 //
       
   272 //
       
   273 void
       
   274 CIPSecPolicyManagerHandler::ConflictTestForPortsAndProtocolL()
       
   275     {
       
   276     const TInt KAddMip4BypassSelectors = (1 << 3);
       
   277 
       
   278     // Set base for the selectors of old policy
       
   279     CSecurityPolicy *oldSp = iPieceData2->Policies();
       
   280     CSelectorList* oldSelectorList = oldSp->SelectorList();
       
   281     TInt oldSelectorCount = oldSelectorList->Count();
       
   282 
       
   283     // Set base for the selectors of new policy
       
   284     CSecurityPolicy *newSp = iPieceData->Policies();
       
   285     CSelectorList* newSelectorList = newSp->SelectorList();
       
   286     TInt newSelectorCount = newSelectorList->Count();
       
   287 
       
   288     // Take the selectors of new policy one by one and
       
   289     // search a selector in the old policy that has the
       
   290     // same address/mask
       
   291     for (TInt i = 0; i < newSelectorCount; i++)
       
   292         {
       
   293         CPolicySelector *newPolicySelector = newSelectorList->At(i);
       
   294 
       
   295         // Iterate into next selector if 'bypass/drop_everything_else'
       
   296         if (IsBypassEverythingElse(*newPolicySelector) 
       
   297             || IsDropEverythingElse(*newPolicySelector))
       
   298             {
       
   299             continue;
       
   300             }
       
   301         
       
   302         // Search a selector from the old policy that address or interface equals
       
   303         for (TInt j = 0; j < oldSelectorCount; j++)
       
   304             {
       
   305             CPolicySelector *oldPolicySelector = oldSelectorList->At(j);
       
   306 
       
   307             // Iterate into next selector if 'bypass/drop_everything_else'
       
   308             if (IsBypassEverythingElse(*oldPolicySelector) 
       
   309                 || IsDropEverythingElse(*oldPolicySelector))
       
   310                 {
       
   311                 continue;
       
   312                 }
       
   313 
       
   314             // Check if different 'interface' and addresses
       
   315             if (!IsEqualInterface(*newPolicySelector, *oldPolicySelector)
       
   316                 && !IsEqualRemoteAddress(*newPolicySelector, *oldPolicySelector)
       
   317                 && !IsEqualLocalAddress(*newPolicySelector, *oldPolicySelector))
       
   318                 {
       
   319                 continue;
       
   320                 }
       
   321 
       
   322             TInt remotePort(oldPolicySelector->iRemote.Port());
       
   323             TInt localPort(oldPolicySelector->iLocal.Port());
       
   324 
       
   325             // Iterate to next selector if DHCP bypass is requested and selector
       
   326             // contains ports utilized with DHCP
       
   327             if ((iFunction & KAddDhcpBypassSelectors) 
       
   328                 && (remotePort == 67 || localPort == 68))
       
   329                 {
       
   330                 continue;
       
   331                 }
       
   332 
       
   333             // Iterate to next selector if IKE bypass is requested and selector 
       
   334             // contains ports utilized with IKE
       
   335             if ((iFunction & KAddIkeBypassSelectors)
       
   336                 && (localPort == 500 || localPort == 4500))
       
   337                 {
       
   338                 continue;
       
   339                 }
       
   340 
       
   341             // Iterate to next selector if MIPv4 bypass is requested and selector 
       
   342             // contains ports utilized with MIPv4
       
   343             if ((iFunction & KAddMip4BypassSelectors)
       
   344                 && (localPort == 434 || remotePort == 434))
       
   345                 {
       
   346                 continue;
       
   347                 }
       
   348   
       
   349             // Matching address found. Check the ports and protocol,
       
   350             // call ComparePortProtocol(). Return codes are:
       
   351             //     0 = Both new and old are without port/protocol
       
   352             //     1 = Only new or old contains port/protocol
       
   353             //     2 = Matching port/protocol and SAs
       
   354             //     3 = Matching port/protocol, but not matching SAs
       
   355             //     4 = Different port/protocols
       
   356             TInt status = ComparePortProtocol(oldPolicySelector, newPolicySelector);
       
   357             
       
   358             if (status == 0)             
       
   359                 {
       
   360                 // Ok: Both new and old are without port/protocol
       
   361                 break;                   
       
   362                 }
       
   363 
       
   364             if (status == 1)
       
   365                 {
       
   366                 // Error: Only new or old contains port/protocol
       
   367                 BuildConflictInfoL();
       
   368                 }
       
   369 
       
   370             if (status == 2)
       
   371                 {
       
   372                 // Ok: Matching port/protocol and SAs
       
   373                 break;
       
   374                 }
       
   375 
       
   376             if (status == 3)
       
   377                 {
       
   378                 // Ok: Matching port/protocol, but not matching SAs
       
   379                 BuildConflictInfoL();
       
   380                 }
       
   381 
       
   382             if (status == 4)
       
   383                 {
       
   384                 // Ok: Different port/protocols
       
   385                 continue;
       
   386                 }
       
   387             }
       
   388         }
       
   389     }
       
   390 
       
   391 //
       
   392 // This function checks whether there are the same port and protocol
       
   393 // codes in two selectors (in old and new policy).
       
   394 // The return codes are:
       
   395 //     0 = Both new and old are without port/protocol
       
   396 //     1 = Only new or old contains port/protocol
       
   397 //     2 = Matching port/protocol and SAs
       
   398 //     3 = Matching port/protocol, but not matching SAs
       
   399 //     4 = Different port/protocol
       
   400 //
       
   401 //
       
   402 TInt
       
   403 CIPSecPolicyManagerHandler::ComparePortProtocol(
       
   404     CPolicySelector *aPolicySelector1,
       
   405     CPolicySelector *aPolicySelector2)
       
   406     {
       
   407     // Check whether the selector 1 and 2 have port and/or protocol
       
   408     TInt portProtocolExists1 = 0;
       
   409     TInt portProtocolExists2 = 0;
       
   410     if (aPolicySelector1->iRemote.Port() != 0 ||
       
   411         aPolicySelector1->iLocal.Port() != 0 ||
       
   412         aPolicySelector1->iProtocol != 0)
       
   413         {
       
   414         portProtocolExists1 = 1;
       
   415         }
       
   416     if (aPolicySelector2->iRemote.Port() != 0 ||
       
   417         aPolicySelector2->iLocal.Port() != 0 ||
       
   418         aPolicySelector2->iProtocol != 0)
       
   419         {
       
   420         portProtocolExists2 = 1;
       
   421         }
       
   422 
       
   423     // Check if both selectors are without port/protocol
       
   424     TInt paramCount = portProtocolExists1 + portProtocolExists2;
       
   425     if (paramCount == 0)
       
   426         {
       
   427         return 0;                    // 0 = Both new and old are without port/protocol
       
   428         }
       
   429 
       
   430     // If the selector 1 contains port or protocol and the selector 2 not,
       
   431     // or vice versa, set return code 1
       
   432 
       
   433     if (paramCount == 1)
       
   434         {
       
   435         return 1;                    // 1 = Only new or old contains port/protocol
       
   436         }
       
   437 
       
   438     // Both the selector 1 and selector 2 have port and/or protocol, check if
       
   439     // they have the same values
       
   440 
       
   441     if (aPolicySelector1->iRemote.Port() == aPolicySelector2->iRemote.Port() 
       
   442         && aPolicySelector1->iLocal.Port() == aPolicySelector2->iLocal.Port() 
       
   443         && aPolicySelector1->iProtocol == aPolicySelector2->iProtocol )
       
   444         {
       
   445         // The selectors have the same values for port and protocol, compare
       
   446         // the SA block parameters
       
   447         TInt err = CompareSAParameters(aPolicySelector2, aPolicySelector1);
       
   448         if (err == KErrNone)
       
   449             {
       
   450             return 2;                // 2 = Matching port/protocol and SAs
       
   451             }
       
   452         else
       
   453             {
       
   454             return 3;                // 3 = Matching port/protocol, but not matching SAs
       
   455             }
       
   456         }
       
   457         
       
   458     return 4;                        // 4 = Different port/protocol
       
   459     }
       
   460 
       
   461 //
       
   462 // Conflict found:
       
   463 // Allocate buffer and copy to it the info section of old
       
   464 // policy file. Call ErrorHandling that leaves
       
   465 //
       
   466 //
       
   467 void
       
   468 CIPSecPolicyManagerHandler::BuildConflictInfoL()
       
   469     {
       
   470     delete iLastConflictInfo;
       
   471     iLastConflictInfo = 0;
       
   472     HBufC* infoBfr = iPieceData2->Info();
       
   473     TPtr ptr = infoBfr->Des();
       
   474     TInt length = ptr.Length();
       
   475     iLastConflictInfo = HBufC8::NewL(length + 1);
       
   476     TPtr8 ptr8(iLastConflictInfo->Des());
       
   477     ptr8.FillZ();
       
   478     ptr8.Copy(ptr);
       
   479     ptr8.ZeroTerminate();
       
   480     
       
   481     ErrorHandlingL(ESelectorConflict , 0);
       
   482     }
       
   483 
       
   484 //
       
   485 // This function compares a selector of new policy given as input
       
   486 // parameter to the selectors of the policy taken from
       
   487 // the Active policy list and checks if the selectors have overlapping
       
   488 // addresses. If a conflict is found, this function calls   .
       
   489 // BuildConflictInfoL() that fills the iLastConflictInfo buffer
       
   490 // and leaves.
       
   491 //
       
   492 //
       
   493 void
       
   494 CIPSecPolicyManagerHandler::CompareSelectorsL(CPolicySelector* aPolicySelector)
       
   495     {
       
   496     TBool overlappingOccurs = EFalse;
       
   497     TInt err = KErrNone;
       
   498 
       
   499     // Set base for the selectors of old policy
       
   500     CSecurityPolicy *sp = iPieceData2->Policies();
       
   501     CSelectorList* selectorList = sp->SelectorList();
       
   502     TInt selectorCount = selectorList->Count();
       
   503 
       
   504     // Take the selectors of old policy one by one and
       
   505     // compare them against the selector of the new policy
       
   506     for (TInt i = 0; i < selectorCount; i++)
       
   507         {
       
   508         CPolicySelector *ps = selectorList->At(i);
       
   509 
       
   510         // Skip comparison if 'bypass/drop_everything_else' action 
       
   511         if (IsBypassEverythingElse(*ps) || IsDropEverythingElse(*ps))
       
   512             {
       
   513             continue;
       
   514             }
       
   515             
       
   516         //  Compare SA parameters if equal 'interface' specific selectors
       
   517         if (IsEqualInterface(*ps, *aPolicySelector))
       
   518             {
       
   519             if (!CompareSAParameters(ps, aPolicySelector))
       
   520                 {
       
   521                 continue;
       
   522                 }
       
   523             else    
       
   524                 {
       
   525                 BuildConflictInfoL();
       
   526                 return;
       
   527                 }
       
   528             }
       
   529             
       
   530         // If no remote address, no conflict
       
   531         if (ps->iRemote.IsUnspecified() 
       
   532             && aPolicySelector->iRemote.IsUnspecified())
       
   533             {
       
   534             continue;
       
   535             }
       
   536 
       
   537         // If different address families, no conflict
       
   538         if (ps->iRemote.Family() != aPolicySelector->iRemote.Family())
       
   539             {
       
   540             continue;
       
   541             }
       
   542         
       
   543         // If different scope IDs, no conflict
       
   544         if (ps->iRemote.Scope() != aPolicySelector->iRemote.Scope())
       
   545             {
       
   546             continue;
       
   547             }
       
   548 
       
   549         // If IPV6 address and not IPv4 Mappped, no conflict (should do something)
       
   550         if (aPolicySelector->iRemote.Family() == KAfInet6 
       
   551             && !aPolicySelector->iRemote.IsV4Mapped())
       
   552             {
       
   553             continue;
       
   554             }
       
   555 
       
   556         // Check address overlapping
       
   557         overlappingOccurs = 
       
   558             CheckAddressOverlapping(aPolicySelector->iRemote.Address(),
       
   559                                     aPolicySelector->iRemoteMask.Address(),
       
   560                                     ps->iRemote.Address(),
       
   561                                     ps->iRemoteMask.Address());
       
   562 
       
   563         if (overlappingOccurs)
       
   564             {
       
   565             err = ESelectorConflict;
       
   566 
       
   567             // Overlapping addresses, check if all parameters match. If
       
   568             // match, no conflict
       
   569             if (aPolicySelector->iRemote.Address() == ps->iRemote.Address() &&
       
   570                 aPolicySelector->iRemoteMask.Address() == ps->iRemoteMask.Address())
       
   571                 {
       
   572                 // Compare SAs.
       
   573                 // If port or protocol exists, the SA tests are already done
       
   574                 err = KErrNone;
       
   575                 if (aPolicySelector->iRemote.Port() == 0 &&
       
   576                     aPolicySelector->iLocal.Port() == 0 &&
       
   577                     aPolicySelector->iProtocol == 0)
       
   578                     {
       
   579                     err = CompareSAParameters(aPolicySelector, ps);
       
   580                     }
       
   581                 }
       
   582             if (err != KErrNone)
       
   583                 {
       
   584                 // Allocate buffer and copy to it the info section of old
       
   585                 // policy file and call ErrorHandling that leaves
       
   586                 BuildConflictInfoL();
       
   587                 }
       
   588             }
       
   589         }
       
   590     }
       
   591 
       
   592 //
       
   593 // CIPSecPolicyManagerHandler::CompareSAParameters()
       
   594 //
       
   595 // This function compares the SA parameters of new policy to the parameters 
       
   596 // of the policy taken from the Active policy list. If any parameter differs, 
       
   597 // conflict found.
       
   598 //
       
   599 //
       
   600 TInt
       
   601 CIPSecPolicyManagerHandler::CompareSAParameters(
       
   602     CPolicySelector *aPolicySelectorNew,
       
   603     CPolicySelector *aPolicySelectorOld)
       
   604     {
       
   605     // Check that there is no conflicts in drop action    
       
   606     if (aPolicySelectorNew->iDropAction != aPolicySelectorOld->iDropAction)
       
   607         return (ESelectorConflict);
       
   608 
       
   609     // Check that there is no conflicts in bypass/transform action
       
   610     if (aPolicySelectorNew->iBundle.IsEmpty() != aPolicySelectorOld->iBundle.IsEmpty())
       
   611         return (ESelectorConflict);
       
   612     
       
   613     // Check that there is no conflicts in policy actions        
       
   614     TInt err(KErrNone);
       
   615     TSecpolBundleIter iterBundleNew(aPolicySelectorNew->iBundle);
       
   616     TSecpolBundleIter iterBundleOld(aPolicySelectorOld->iBundle);
       
   617     while (1)
       
   618         {
       
   619         CSecpolBundleItem* itemBundleNew(NULL);
       
   620         CSecpolBundleItem* itemBundleOld(NULL);
       
   621         TSecurityAssocSpec* specNew(NULL);
       
   622         TSecurityAssocSpec* specOld(NULL);
       
   623 
       
   624         // Retrieve next bundle items from the list
       
   625         itemBundleNew = iterBundleNew++;
       
   626         itemBundleOld = iterBundleOld++;
       
   627 
       
   628         if (!itemBundleNew && !itemBundleOld)
       
   629             {
       
   630             // Equal count of bundle items so stop iteration, no conflicts
       
   631             break;
       
   632             }
       
   633 
       
   634         if (!itemBundleNew || !itemBundleOld)
       
   635             {
       
   636             // Different count of bundle items so stop iteration, conflict
       
   637             err = ESelectorConflict;
       
   638             break;
       
   639             }
       
   640 
       
   641         // Verify bundle items to find out if conflicts exist 
       
   642 
       
   643         if (itemBundleNew->iSpec)
       
   644             {
       
   645             specNew = &itemBundleNew->iSpec->iSpec;
       
   646             }
       
   647             
       
   648         if (itemBundleOld->iSpec)
       
   649             {
       
   650             specOld = &itemBundleOld->iSpec->iSpec;
       
   651             }
       
   652 
       
   653         // Verify SA Transform Template attributes
       
   654 #ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
       
   655         if (!IsEqualSaSpec(itemBundleNew, itemBundleOld))
       
   656 #else
       
   657         if (!IsEqualSaSpec(specNew, specOld))
       
   658 #endif //SYMBIAN_IPSEC_VOIP_SUPPORT
       
   659             {
       
   660             err = ESelectorConflict;
       
   661             break;
       
   662             }
       
   663 
       
   664         // Verify Remote/Local Identity values
       
   665         if (itemBundleNew->iSpec && itemBundleOld->iSpec)
       
   666             {
       
   667             TDesC8* id1 = itemBundleNew->iSpec->iRemoteIdentity;
       
   668             TDesC8* id2 = itemBundleOld->iSpec->iRemoteIdentity;
       
   669 
       
   670             if ((!id1 && id2) || (id1 && !id2))
       
   671                 {
       
   672                 err = ESelectorConflict;
       
   673                 break;
       
   674                 }
       
   675                 
       
   676             if (id1 && id2 && (id1->Compare(*id2)))
       
   677                 {
       
   678                 err = ESelectorConflict;
       
   679                 break;
       
   680                 }
       
   681 
       
   682             id1 = itemBundleNew->iSpec->iLocalIdentity;
       
   683             id2 = itemBundleOld->iSpec->iLocalIdentity;
       
   684 
       
   685             if ((!id1 && id2) || (id1 && !id2))
       
   686                 {
       
   687                 err = ESelectorConflict;
       
   688                 break;
       
   689                 }
       
   690 
       
   691             if (id1 && id2 && (id1->Compare(*id2)))
       
   692                 {
       
   693                 err = ESelectorConflict;
       
   694                 break;
       
   695                 }
       
   696             }
       
   697         }
       
   698 
       
   699     return (err);
       
   700     }
       
   701 
       
   702 //
       
   703 // This function examines whether the addresses in the Net1 and Net2 are
       
   704 // overlapping
       
   705 //
       
   706 // return = ETrue, overlapping addresses or illegal mask
       
   707 //          EFalse, not overlapping
       
   708 //
       
   709 //
       
   710 TBool 
       
   711 CIPSecPolicyManagerHandler::CheckAddressOverlapping(
       
   712     TUint32 aNet1IpAddress,     // Net1 low address
       
   713     TUint32 aNet1Mask,          // Net1 mask
       
   714     TUint32 aNet2IpAddress,     // Net2 low address
       
   715     TUint32 aNet2Mask)          // Net2 mask
       
   716     {
       
   717     TInt err;
       
   718     TUint32 net1IpAddressLow;
       
   719     TUint32 net1IpAddressHigh;
       
   720     TUint32 net2IpAddressLow;
       
   721     TUint32 net2IpAddressHigh;
       
   722 
       
   723     // Calculate Net1 low and high address values (range)
       
   724     net1IpAddressLow = aNet1IpAddress & aNet1Mask;
       
   725     err = GetRangeHighAddress(net1IpAddressHigh, net1IpAddressLow, aNet1Mask);
       
   726     if (err)
       
   727         {
       
   728         return ETrue; /* Illegal mask value */
       
   729         }
       
   730     if ( net1IpAddressHigh == 0 )
       
   731         {
       
   732         net1IpAddressHigh = net1IpAddressLow;
       
   733         }
       
   734 
       
   735     // Calculate Net2 low and high address values (range)
       
   736     net2IpAddressLow = aNet2IpAddress & aNet2Mask;
       
   737     err = GetRangeHighAddress(net2IpAddressHigh, net2IpAddressLow, aNet2Mask);
       
   738     if (err)
       
   739         {
       
   740         return ETrue; /* Illegal mask value */
       
   741         }
       
   742     if (net2IpAddressHigh == 0)
       
   743         {
       
   744         net2IpAddressHigh = net2IpAddressLow;
       
   745         }
       
   746 
       
   747     // Check if Net1 and Net 2 are overlapping
       
   748     if (net1IpAddressHigh >= net2IpAddressLow 
       
   749         && net1IpAddressLow <= net2IpAddressHigh)
       
   750         {
       
   751         return ETrue;   /* overlapping occurs */
       
   752         }
       
   753 
       
   754     if (net2IpAddressHigh >= net1IpAddressLow 
       
   755         && net2IpAddressLow <= net1IpAddressHigh)
       
   756         {
       
   757         return ETrue;   /* overlapping occurs */
       
   758         }
       
   759 
       
   760     return EFalse;
       
   761     }
       
   762 
       
   763 //
       
   764 // This is a subfunction for the overlapping test. The function
       
   765 // builds the high range address from the low range and mask.
       
   766 //
       
   767 // return = 0 = OK high range returned in aNetIpAddressHigh parameter.
       
   768 //          1 = illegal mask format, 0-bit between 1-bits
       
   769 //
       
   770 //
       
   771 TInt 
       
   772 CIPSecPolicyManagerHandler::GetRangeHighAddress(
       
   773     TUint32& aNetIpAddressHigh,
       
   774     TUint32 aNetIpAddressLow,
       
   775     TUint32 aNetMask)
       
   776     {
       
   777     TUint32 refBit = 1;
       
   778     TUint32 refMask = 0xffffffff;
       
   779 
       
   780     // Adjust range high address from IP address/mask pair
       
   781     // Find the first (= lowest) 1-bit in mask and assure
       
   782     // that there is no high order 0-bits in mask
       
   783     while (refBit && ((aNetMask & refBit) == 0))
       
   784         {
       
   785         refMask &= (~refBit);
       
   786         refBit = refBit << 1;
       
   787         }
       
   788 
       
   789     if ((aNetMask & refMask) == refMask)
       
   790         {
       
   791         aNetIpAddressHigh = aNetIpAddressLow | ~aNetMask;
       
   792         refBit = 0;
       
   793         }
       
   794     else
       
   795         {
       
   796         refBit = 1;  /* error */
       
   797         }
       
   798 
       
   799     return refBit;
       
   800     }