vpnengine/vpnmanager/src/policystore.cpp
changeset 0 33413c0669b9
child 20 352850cbed81
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2000-2007 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:   Policy store
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include <e32math.h>
       
    21 #include <cmconnectionmethod.h>
       
    22 #include <cmpluginvpndef.h> // vpn plugin
       
    23 #include "policystore.h"
       
    24 #include "pinparser.h"
       
    25 #include "ikepolparser.h"
       
    26 #include "pkiserviceapi.h"
       
    27 #include "policyimporter.h"
       
    28 #include "uuid.h"
       
    29 #include "log_r6.h"
       
    30 
       
    31 CPolicyStore* CPolicyStore::NewL(RFs& aFs)
       
    32     {
       
    33     CPolicyStore* self = new (ELeave) CPolicyStore(aFs);
       
    34     CleanupStack::PushL(self);
       
    35     self->ConstructL();
       
    36     CleanupStack::Pop(); // self
       
    37     return self;
       
    38     }
       
    39 
       
    40 CPolicyStore::CPolicyStore(RFs& aFs) : iFs(aFs), iFileUtil(aFs)
       
    41     {
       
    42     }
       
    43 
       
    44 inline void CPolicyStore::ConstructL()
       
    45     {
       
    46     LOG_("CPolicyStore::ConstructL");    
       
    47     ConstructPolicyListL();
       
    48     LOG_("CPolicyStore::ConstructL:end");    
       
    49     }
       
    50 
       
    51 CPolicyStore::~CPolicyStore()
       
    52     {
       
    53     delete iPolicyListAll;
       
    54     delete iPolicyListVisible;
       
    55     }
       
    56 
       
    57 void CPolicyStore::ConstructPolicyListL()
       
    58     {
       
    59     // Using two policy lists (one for all and one for the visible
       
    60     // ones) makes it easy to support the concept of hidden and
       
    61     // visible policies. There's a slight memory penalty but this
       
    62     // is not serious as the number of policies is typically small).
       
    63     // Hidden policies differ from visible ones in only one aspect - 
       
    64     // they are not included in the policy listing returned to
       
    65     // the caller.
       
    66     
       
    67     // A list of all policies (both visible and hidden)
       
    68     iPolicyListAll = new (ELeave) CArrayFixFlat<TVpnPolicyInfo>(2);
       
    69     // A list of visible policies only
       
    70     iPolicyListVisible = new (ELeave) CArrayFixFlat<TVpnPolicyInfo>(2);
       
    71 
       
    72     TFindFile fileFinder(iFs);
       
    73     CDir* fileList; 
       
    74 
       
    75     TPath privateDir;
       
    76     User::LeaveIfError(iFs.PrivatePath(privateDir));
       
    77     TInt ret = fileFinder.FindWildByDir(KPolFilePat, privateDir, fileList);
       
    78     if (ret == KErrNone)
       
    79         {
       
    80         CleanupStack::PushL(fileList);
       
    81         
       
    82         for (TInt i = 0; i < fileList->Count(); i++)
       
    83             {
       
    84             TParse fileNameParser;
       
    85             fileNameParser.Set((*fileList)[i].iName, &fileFinder.File(), NULL);
       
    86 
       
    87             TVpnPolicyId policyId;
       
    88             
       
    89             // Only add the policy to the list its ID length is
       
    90             // acceptable (this is the case with all policies
       
    91             // that have been properly imported to the store)
       
    92             if (fileNameParser.Name().Length() <= policyId.MaxLength())
       
    93                 {
       
    94                 policyId.Copy(fileNameParser.Name());
       
    95 
       
    96                 HBufC* pinFile = iFileUtil.GetPinFileNameLC(policyId);
       
    97 
       
    98                 if (iFileUtil.FileExists(*pinFile))
       
    99                     {
       
   100                     AddPolicyL(policyId);
       
   101                     }
       
   102                 CleanupStack::PopAndDestroy(pinFile);
       
   103                 }
       
   104             }
       
   105         
       
   106         CleanupStack::PopAndDestroy(); // fileList
       
   107         }
       
   108     }
       
   109 
       
   110 TUint8* CPolicyStore::RawPolicyData()
       
   111     {
       
   112     // The list of policies returned to the caller contains ONLY
       
   113     // visible policies. 
       
   114     return reinterpret_cast<TUint8*>(&(iPolicyListVisible->At(0)));
       
   115     }
       
   116 
       
   117 void CPolicyStore::ImportPolicyL(
       
   118     const TFileName& aPinFile, const TFileName& aPolFile,
       
   119     TVpnPolicyId* aNewPolicyId)
       
   120     {
       
   121     LOG_("-> CPolicyStore::ImportPolicyL()");            
       
   122     TVpnPolicyId policyId = NewPolicyIdL();
       
   123 
       
   124     // Write the new policy ID to the caller
       
   125     if (aNewPolicyId)
       
   126         {
       
   127         aNewPolicyId->Copy(policyId);
       
   128         }
       
   129 
       
   130     // Create new PIN and POL file names
       
   131     // (Dynamic allocation to conserve stack space)
       
   132     HBufC* pinFileP = iFileUtil.GetPinFileNameLC(policyId);
       
   133     HBufC* polFileP = iFileUtil.GetPolFileNameLC(policyId);
       
   134 
       
   135     // Move the files from the install directory
       
   136     // to the target directory (the policy store)
       
   137     iFileUtil.CopyFileL(aPinFile, *pinFileP);
       
   138     iFileUtil.CopyFileL(aPolFile, *polFileP);
       
   139 
       
   140     CleanupStack::PopAndDestroy(polFileP);
       
   141 
       
   142     // Make sure that the name of the new policy
       
   143     // does not collide with an existing name
       
   144     EnsureUniquePolicyNameL(*pinFileP);
       
   145 
       
   146     CleanupStack::PopAndDestroy(pinFileP);
       
   147     
       
   148     // Add the imported policy to the policy list
       
   149     AddPolicyL(policyId);
       
   150     LOG(Log::Printf(_L("<- CPolicyStore::ImportPolicyL()")));            
       
   151     }
       
   152 
       
   153 TInt CPolicyStore::DeletePolicyL(const TVpnPolicyId& aPolicyId)
       
   154     {
       
   155     LOG(Log::Printf(_L("-> CPolicyStore::DeletePolicyL()")));            
       
   156     // Delete the policy from the list of all policies
       
   157     
       
   158     TInt itemToDelete = PolicyIndex(aPolicyId);
       
   159     
       
   160     if (itemToDelete != KUnfoundIndex)
       
   161         {
       
   162         iPolicyListAll->Delete(itemToDelete);
       
   163         iPolicyListAll->Compress();
       
   164         }
       
   165 
       
   166     // Delete the policy also from the list of
       
   167     // visible policies if it happens to be there
       
   168     
       
   169     TInt itemToDeleteVisible = PolicyIndexVisible(aPolicyId);
       
   170     
       
   171     if (itemToDeleteVisible != KUnfoundIndex)
       
   172         {
       
   173         iPolicyListVisible->Delete(itemToDeleteVisible);
       
   174         iPolicyListVisible->Compress();
       
   175         }
       
   176 
       
   177     // Delete the PIN and POL files
       
   178     HBufC* pinFile = iFileUtil.GetPinFileNameLC(aPolicyId);    
       
   179     HBufC* polFile = iFileUtil.GetPolFileNameLC(aPolicyId);
       
   180 
       
   181     if (iFileUtil.FileExists(*pinFile))
       
   182         {
       
   183         iFileUtil.DeleteFileL(*pinFile); 
       
   184         }
       
   185     
       
   186     if (iFileUtil.FileExists(*polFile))
       
   187         {
       
   188         iFileUtil.DeleteFileL(*polFile);
       
   189         }
       
   190     CleanupStack::PopAndDestroy(2); // polFile, pinFile
       
   191     LOG(Log::Printf(_L("<- CPolicyStore::DeletePolicyL()")));            
       
   192     return KErrNone;
       
   193     }
       
   194     
       
   195 TInt CPolicyStore::PolicyCount()
       
   196     {
       
   197     // The list of policies returned to the caller contains ONLY
       
   198     // visible policies. Thus we return just the count of those.
       
   199     return iPolicyListVisible->Count();
       
   200     }
       
   201 
       
   202 TInt CPolicyStore::GetPolicyInfo(const TVpnPolicyId& aPolicyId, TVpnPolicyInfo& aPolicyInfo)
       
   203     {
       
   204     TInt policyIndex = PolicyIndex(aPolicyId);
       
   205     
       
   206     if (policyIndex == KUnfoundIndex)
       
   207         {
       
   208         return KVpnErrPolicyNotFound;
       
   209         }
       
   210     else
       
   211         {
       
   212         aPolicyInfo = iPolicyListAll->At(policyIndex);
       
   213         return KErrNone;
       
   214         }
       
   215     }
       
   216 
       
   217 TInt CPolicyStore::GetPolicyDetailsL(
       
   218     const TVpnPolicyId& aPolicyId, 
       
   219     TVpnPolicyDetails& aPolicyDetails)
       
   220     {
       
   221     LOG(Log::Printf(_L("-> CPolicyStore::GetPolicyDetailsL()")));            
       
   222     TInt policyIndex = PolicyIndex(aPolicyId);
       
   223     
       
   224     if (policyIndex == KUnfoundIndex)
       
   225         {
       
   226         LOG(Log::Printf(_L("<- CPolicyStore::GetPolicyDetailsL() (KVpnErrPolicyNotFound)")));
       
   227         return KVpnErrPolicyNotFound;
       
   228         }
       
   229     else
       
   230         {
       
   231         STACK_LEFT;
       
   232         
       
   233         // Get static policy information from the PIN file
       
   234         TPinParser* pinParser = new (ELeave) TPinParser(iFileUtil);
       
   235         CleanupStack::PushL(pinParser);
       
   236 
       
   237         HBufC* pinFile = iFileUtil.GetPinFileNameLC(aPolicyId);
       
   238         pinParser->ParsePolicyDetailsL(*pinFile, aPolicyDetails);
       
   239 
       
   240         CleanupStack::PopAndDestroy(2); // pinFile, pinParser
       
   241 
       
   242         // Find out dynamic policy information from the system
       
   243         aPolicyDetails.iPkiStatus = PolicyPkiStatusL(aPolicyId);
       
   244         aPolicyDetails.iUsageStatus = 
       
   245             PolicyUsageStatusL(aPolicyId);
       
   246         // Set the policy ID as well
       
   247         aPolicyDetails.iId.Copy(aPolicyId);
       
   248         
       
   249         LOG(Log::Printf(_L("<- CPolicyStore::GetPolicyDetailsL()")));
       
   250         return KErrNone;
       
   251         }
       
   252     }
       
   253 
       
   254 TInt CPolicyStore::LoadPolicyDataL(const TVpnPolicyId& aPolicyId, 
       
   255     HBufC8*& aPolicyData)
       
   256     {
       
   257     TInt policyIndex = PolicyIndex(aPolicyId);
       
   258     
       
   259     if (policyIndex == KUnfoundIndex)
       
   260         {
       
   261         return KVpnErrPolicyNotFound;
       
   262         }
       
   263     HBufC* polFile = iFileUtil.GetPolFileNameLC(aPolicyId);
       
   264     
       
   265     aPolicyData = iFileUtil.LoadFileDataL(*polFile);
       
   266 
       
   267     CleanupStack::PopAndDestroy();
       
   268     return KErrNone;
       
   269     }
       
   270 
       
   271 void CPolicyStore::AddPolicyL(const TVpnPolicyId& aPolicyId)
       
   272     {
       
   273     LOG(Log::Printf(_L("-> CPolicyStore::AddPolicyL")));    
       
   274 
       
   275     TVpnPolicyInfo* policyInfo = new (ELeave) TVpnPolicyInfo();
       
   276     CleanupStack::PushL(policyInfo);
       
   277 
       
   278     policyInfo->iId = aPolicyId;
       
   279     // Policy name is read from the PIN file
       
   280     HBufC* pinFile = iFileUtil.GetPinFileNameLC(aPolicyId);
       
   281 
       
   282     TPinParser* pinParser = new (ELeave) TPinParser(iFileUtil);
       
   283     CleanupStack::PushL(pinParser);
       
   284 
       
   285     pinParser->ParsePolicyInfoL(*pinFile, *policyInfo);
       
   286     
       
   287     CleanupStack::PopAndDestroy(pinParser);
       
   288     CleanupStack::PopAndDestroy(pinFile);
       
   289 
       
   290     LOG(Log::Printf(_L("pinParser.ParsePolicyInfoL completed")));
       
   291     iPolicyListAll->AppendL(*policyInfo);
       
   292 
       
   293     // A visible policy is added also
       
   294     // to the list of visible policies
       
   295     if (!IsHiddenPolicyL(policyInfo->iId))
       
   296         {
       
   297         iPolicyListVisible->AppendL(*policyInfo);
       
   298         }
       
   299 
       
   300     CleanupStack::PopAndDestroy(policyInfo);
       
   301     LOG(Log::Printf(_L("<- CPolicyStore::AddPolicyL")));            
       
   302     }
       
   303 
       
   304 TVpnPolicyId CPolicyStore::NewPolicyIdL()
       
   305     {
       
   306     TUuid uuid;
       
   307     TUuidString uuidString;
       
   308     
       
   309     Uuid::MakeUuidL(uuid);
       
   310 
       
   311     // It has become apparent that certain
       
   312     // Symbian OS devices generate duplicate random
       
   313     // number sequences after gold boot due to improper
       
   314     // seeding of the random number generator. Should
       
   315     // this happen to be the case, we insert at least
       
   316     // one component to the UUID that depends on the 
       
   317     // current system time. This is not perfect, but 
       
   318     // should give us policy IDs that are unique enough.
       
   319     TTime now;
       
   320 	now.UniversalTime();
       
   321     TInt64 randSeed = now.Int64();
       
   322     TInt randomNum = Math::Rand(randSeed);
       
   323     uuid.iTimeLow = static_cast<TUint32>(randomNum);
       
   324     
       
   325     Uuid::UuidToString(uuid, uuidString);
       
   326 
       
   327     TVpnPolicyId newPolicyId;
       
   328     newPolicyId.Copy(uuidString);
       
   329     
       
   330     return newPolicyId;
       
   331     }
       
   332     
       
   333 TInt CPolicyStore::PolicyIndex(const TVpnPolicyId& aPolicyId)
       
   334     {
       
   335     for (TInt i = 0; i < iPolicyListAll->Count(); i++)
       
   336         {
       
   337         if (iPolicyListAll->At(i).iId.Compare(aPolicyId) == 0)
       
   338             {
       
   339             return i;
       
   340             }
       
   341         }
       
   342     LOG_1("CPolicyStore::PolicyIndex not found:%S", &aPolicyId);
       
   343     return KUnfoundIndex;
       
   344     }
       
   345 
       
   346 TInt CPolicyStore::PolicyIndexVisible(const TVpnPolicyId& aPolicyId)
       
   347     {
       
   348     for (TInt i = 0; i < iPolicyListVisible->Count(); i++)
       
   349         {
       
   350         if (iPolicyListVisible->At(i).iId.Compare(aPolicyId) == 0)
       
   351             {
       
   352             return i;
       
   353             }
       
   354         }
       
   355     return KUnfoundIndex;
       
   356     }
       
   357     
       
   358 TPolicyUsageStatus CPolicyStore::PolicyUsageStatusL(
       
   359     const TVpnPolicyId& aPolicyId )
       
   360     {
       
   361     
       
   362     LOG(Log::Printf(_L("-> CPolicyStore::PolicyUsageStatusL")));
       
   363     
       
   364     STACK_LEFT;
       
   365     
       
   366     TPolicyUsageStatus usageStatus = EUsageStatusUnused;
       
   367 
       
   368 using namespace CMManager;    
       
   369     RCmManager cmManager;
       
   370     cmManager.OpenL(); // Do not use LC it's not working yet
       
   371     CleanupClosePushL( cmManager );
       
   372     
       
   373     TBool policyActive(EFalse);
       
   374     if (PolicyAssignedToIapL(cmManager, aPolicyId, policyActive))
       
   375         {
       
   376         usageStatus = policyActive ? EUsageStatusActive : 
       
   377             EUsageStatusAssignedToIap;
       
   378         }
       
   379     CleanupStack::PopAndDestroy(); // cmManager
       
   380     
       
   381     LOG(Log::Printf(_L("<- CPolicyStore::PolicyUsageStatusL")));
       
   382     return usageStatus;
       
   383     }
       
   384 
       
   385 TBool CPolicyStore::PolicyAssignedToIapL(
       
   386     RCmManager& aCmManager,
       
   387     const TVpnPolicyId& aPolicyId,
       
   388     TBool& aPolicyActive)
       
   389     {
       
   390     STACK_LEFT;
       
   391              
       
   392     RArray<TUint32> vpnConnections;
       
   393     ConnectionMethodsLC( 
       
   394         vpnConnections, aCmManager, aPolicyId, aPolicyActive );
       
   395     
       
   396     TBool policyAssignedToIap( vpnConnections.Count() ? ETrue : EFalse );
       
   397     CleanupStack::PopAndDestroy(); // vpnConnections
       
   398     LOG_1("CPolicyStore::PolicyAssignedToIapL %d", policyAssignedToIap); 
       
   399     return policyAssignedToIap;
       
   400     }
       
   401 
       
   402 void CPolicyStore::ConnectionMethodsLC(
       
   403     RArray<TUint32>& aVpnConnections,
       
   404     RCmManager& aCmManager,
       
   405     const TVpnPolicyId& aPolicyId,
       
   406     TBool& aPolicyActive)
       
   407     {
       
   408 using namespace CMManager;         
       
   409     LOG_1("CPolicyStore::ConnectionMethodsLC : %S", &aPolicyId);
       
   410     CleanupClosePushL( aVpnConnections );
       
   411 
       
   412     aCmManager.ConnectionMethodL( 
       
   413         aVpnConnections,
       
   414         ETrue,
       
   415         EFalse,
       
   416         EFalse ); 
       
   417     LOG_1("CPolicyStore::ConnectionMethodsLC cnt: %d", 
       
   418         aVpnConnections.Count());
       
   419     
       
   420     TInt index(aVpnConnections.Count());
       
   421     
       
   422     while( index )
       
   423         {
       
   424         --index;
       
   425         LOG_1("CPolicyStore::ConnectionMethodsLC at: %d", index);
       
   426         TUint32 id(aVpnConnections[index]);
       
   427         RCmConnectionMethod connectioMethod = 
       
   428             aCmManager.ConnectionMethodL( id );
       
   429         CleanupClosePushL( connectioMethod );  
       
   430         if( connectioMethod.GetIntAttributeL(ECmBearerType) != 
       
   431             KPluginVPNBearerTypeUid )
       
   432             {
       
   433             aVpnConnections.Remove( index );
       
   434             }
       
   435         else
       
   436             {
       
   437             HBufC* policyId = connectioMethod.GetStringAttributeL(
       
   438                 EVpnServicePolicy);
       
   439             if( aPolicyId.Compare( *policyId ) )
       
   440                 {
       
   441                 aVpnConnections.Remove( index );
       
   442                 }
       
   443             else
       
   444                 {
       
   445                 if( connectioMethod.GetBoolAttributeL(ECmConnected) )
       
   446                     {
       
   447                     LOG_1("PolicyActiveL:%d", index);
       
   448                     aPolicyActive = ETrue;
       
   449                     }
       
   450                 }
       
   451             delete policyId;      
       
   452             }
       
   453         CleanupStack::PopAndDestroy(); // connectioMethod 
       
   454         }
       
   455     }
       
   456 
       
   457 TPolicyPkiStatus CPolicyStore::PolicyPkiStatusL(const TVpnPolicyId& aPolicyId)
       
   458     {
       
   459     HBufC8* policyData;
       
   460     
       
   461     if (LoadPolicyDataL(aPolicyId, policyData) != KErrNone)
       
   462         {
       
   463         return EPkiStatusUnknown;
       
   464         }
       
   465     
       
   466     CleanupStack::PushL(policyData);
       
   467 
       
   468     HBufC* policyData16 = HBufC::NewL(policyData->Length());
       
   469     CleanupStack::PushL(policyData16);
       
   470     
       
   471     policyData16->Des().Copy(*policyData);
       
   472 
       
   473     CIkeDataArray* ikeDataArray = CIkeDataArray::NewL(1);
       
   474     CleanupStack::PushL(ikeDataArray);
       
   475     
       
   476     TIkeParser ikeParser(*policyData16);
       
   477     ikeParser.ParseIKESectionsL(ikeDataArray);
       
   478 
       
   479     // Go through each IKE section (VPN gateway definition)
       
   480     // to find out the collective policy PKI status:
       
   481     // - EPkiStatusReady if a valid user certificate is present for
       
   482     // each VPN gateway defined in the policy
       
   483     // - EPkiStatusNoCert if no user certificate is present for
       
   484     // one or more VPN gateway defined in the policy
       
   485     // - EPkiStatusCertExpired if a user certificate related
       
   486     // to one or more VPN gateway has expired
       
   487     // - EPkiStatusCertNotValidYet if a user certificate related
       
   488     // to one or more VPN gateway is not yet valid
       
   489     
       
   490     TPolicyPkiStatus policyPkiStatus = EPkiStatusReady;
       
   491     
       
   492     for (TInt i = 0; i < ikeDataArray->Count(); i++)
       
   493         {
       
   494         CIkeData* ikeData = ikeDataArray->At(i);
       
   495 
       
   496         TCertStatus gwPkiStatus = PolicyCertificateStatusL(ikeData);
       
   497 
       
   498         // Determine the overall policy PKI status
       
   499         
       
   500         if (gwPkiStatus == ECertValid ||
       
   501             gwPkiStatus == ECertNotNeeded)
       
   502             {
       
   503             continue;
       
   504             }
       
   505         else if (gwPkiStatus == ECertNotFound)
       
   506             {
       
   507             policyPkiStatus = EPkiStatusNoCert;
       
   508             break;
       
   509             }
       
   510         else if (gwPkiStatus == ECertExpired)
       
   511             {
       
   512             policyPkiStatus = EPkiStatusCertExpired;
       
   513             break;
       
   514             }
       
   515         else if (gwPkiStatus == ECertNotValidYet)
       
   516             {
       
   517             policyPkiStatus = EPkiStatusCertNotValidYet;
       
   518             }
       
   519         }
       
   520 
       
   521     CleanupStack::PopAndDestroy(3); // ikeDataArray, policyData16, policyData
       
   522     
       
   523     return policyPkiStatus;
       
   524     }
       
   525          
       
   526 
       
   527 
       
   528 TCertStatus CPolicyStore::PolicyCertificateStatusL(CIkeData* aIkeData) const
       
   529     {
       
   530     LOG(Log::Printf(_L("-> CPolicyStore::PolicyCertificateStatusL()")));
       
   531     TCertStatus status = ECertValid;
       
   532 
       
   533     CArrayFixFlat<TCertInfo*> *cAList = aIkeData->iCAList;
       
   534     if ((cAList == NULL || cAList->Count() == 0) && 
       
   535         !aIkeData->iOwnCert.iOwnCertExists)
       
   536         {
       
   537         status = ECertNotNeeded;
       
   538         }
       
   539     else
       
   540         {        
       
   541         RPKIServiceAPI pkiService;
       
   542         User::LeaveIfError(pkiService.Connect());
       
   543         CleanupClosePushL(pkiService);
       
   544 
       
   545         pkiService.SetInformational(ETrue);
       
   546                     
       
   547         CDesC8ArrayFlat* caSubjectNameArray = new (ELeave) CDesC8ArrayFlat(2);
       
   548         CleanupStack::PushL(caSubjectNameArray);                        
       
   549             
       
   550         if (cAList != NULL && cAList->Count() > 0)
       
   551             {                    
       
   552             status = PkiUtil::GetValidCaCertSubjectNameListL(pkiService, *cAList,
       
   553                                                              *caSubjectNameArray);        
       
   554             }
       
   555             
       
   556         if (status == ECertValid)
       
   557             {
       
   558 			// Set store type to device store,
       
   559 			// if Own_cert_type is defined as "DEVICE"            
       
   560 			if ( aIkeData->iClientCertType != NULL )
       
   561 			  	{
       
   562 				TPtrC16 certStoreType = aIkeData->iClientCertType->GetData();
       
   563 				if ( certStoreType.CompareF(_L("DEVICE")) == 0 )
       
   564 					{
       
   565 					LOG(Log::Printf(_L("Set store type to STORETYPE_DEVICE")));    
       
   566 					pkiService.SetStoreType(EPkiStoreTypeDevice);            
       
   567 					}
       
   568                 else
       
   569                     {
       
   570 					LOG(Log::Printf(_L("Set store type to STORETYPE_USER")));    
       
   571 					pkiService.SetStoreType(EPkiStoreTypeUser);                                
       
   572                     }
       
   573 				}
       
   574             else
       
   575                 {
       
   576 				LOG(Log::Printf(_L("Set store type to STORETYPE_USER")));    
       
   577 				pkiService.SetStoreType(EPkiStoreTypeUser);                                                
       
   578                 }
       
   579             status = PkiUtil::CheckUserCertValidityL(pkiService, *caSubjectNameArray,
       
   580                                                      aIkeData->iOwnCert);
       
   581             }
       
   582         CleanupStack::PopAndDestroy(caSubjectNameArray);
       
   583         CleanupStack::PopAndDestroy(); //pkiService            
       
   584         }
       
   585 	LOG(Log::Printf(_L("<- CPolicyStore::PolicyCertificateStatusL()")));        
       
   586     return status;
       
   587     }
       
   588 
       
   589 
       
   590 
       
   591 void CPolicyStore::EnsureUniquePolicyNameL(const TFileName& aPinFile)
       
   592     {
       
   593     LOG_("-> CPolicyStore::EnsureUniquePolicyNameL");
       
   594 
       
   595     // Dynamic allocations to conserve stack space
       
   596 
       
   597     TVpnPolicyDetails* policyDetails = new (ELeave) TVpnPolicyDetails();
       
   598     CleanupStack::PushL(policyDetails);
       
   599 
       
   600     TPinParser* pinParserP = new (ELeave) TPinParser(iFileUtil);
       
   601     CleanupStack::PushL(pinParserP);
       
   602             
       
   603     pinParserP->ParsePolicyDetailsL(aPinFile, *policyDetails);
       
   604 
       
   605     TBool policyNameChanged = DoEnsureUniquePolicyNameL(*policyDetails);
       
   606 
       
   607     if (policyNameChanged)
       
   608         {
       
   609         HBufC* pinFileContent = pinParserP->PolicyDetailsAsTextL(*policyDetails);
       
   610         CleanupStack::PushL(pinFileContent);
       
   611 
       
   612         iFileUtil.SaveFileDataL(aPinFile, *pinFileContent);
       
   613 
       
   614         CleanupStack::PopAndDestroy(pinFileContent); // pinFileContent
       
   615         }
       
   616     CleanupStack::PopAndDestroy(); // pinParserP
       
   617     CleanupStack::PopAndDestroy(); // policyDetails
       
   618 
       
   619     LOG_("<- CPolicyStore::EnsureUniquePolicyNameL");
       
   620     }
       
   621 
       
   622 TBool CPolicyStore::DoEnsureUniquePolicyNameL(TVpnPolicyDetails& aPolicyDetails)     
       
   623     {
       
   624     
       
   625     LOG(Log::Printf(_L("-> CPolicyStore::DoEnsureUniquePolicyNameL")));    
       
   626     TBool nameChanged = EFalse;
       
   627     TBool isUnique = EFalse;
       
   628     
       
   629     HBufC* newName = aPolicyDetails.iName.AllocLC();
       
   630     TInt sequenceNumber = 2;
       
   631     
       
   632     while (!isUnique && sequenceNumber < KMaxTInt)
       
   633         {
       
   634         if (PolicyNameExists(*newName))
       
   635             {
       
   636             if (newName != NULL) 
       
   637                 {
       
   638                 CleanupStack::PopAndDestroy(newName);
       
   639                 LOG_(" Pop (newName)");
       
   640                 newName = NULL;
       
   641                 }
       
   642             newName = MakeNewPolicyNameL(aPolicyDetails.iName, sequenceNumber);
       
   643             CleanupStack::PushL(newName);
       
   644 
       
   645             sequenceNumber++;
       
   646 
       
   647             nameChanged = ETrue;
       
   648             }
       
   649         else
       
   650             {
       
   651             isUnique = ETrue;
       
   652             }
       
   653         }
       
   654 
       
   655     if (nameChanged)
       
   656         {
       
   657         // We now have a new unique policy name so we can save it
       
   658         // Make sure there's no risk of overflow
       
   659         aPolicyDetails.iName.Copy(newName->Left(aPolicyDetails.iName.MaxLength()));
       
   660         }
       
   661     
       
   662     if (newName != NULL) 
       
   663         {
       
   664         CleanupStack::PopAndDestroy(); // newName
       
   665         }
       
   666     
       
   667     LOG(Log::Printf(_L("<- CPolicyStore::DoEnsureUniquePolicyName")));    
       
   668     return nameChanged;
       
   669     }
       
   670 
       
   671 TBool CPolicyStore::PolicyNameExists(const TDesC& aPolicyName)
       
   672     {
       
   673     LOG_("-> CPolicyStore::PolicyNameExists");
       
   674     TBool policyNameExists = EFalse;
       
   675     
       
   676     // Check the name against the existing names
       
   677     for (TInt i = 0; i < iPolicyListAll->Count(); i++)
       
   678         {
       
   679         // Ignore case in the name comparison
       
   680         if (iPolicyListAll->At(i).iName.CompareF(aPolicyName) == 0)
       
   681             {
       
   682             policyNameExists = ETrue;
       
   683             break;
       
   684             }
       
   685         }
       
   686 
       
   687     LOG_("<- CPolicyStore::PolicyNameExists");    
       
   688     return policyNameExists;
       
   689     }
       
   690 
       
   691 HBufC* CPolicyStore::MakeNewPolicyNameL(const TDes& aOriginalPolicyName, 
       
   692                                      TInt aSequenceNumber)
       
   693     {
       
   694     LOG_("-> CPolicyStore::MakeNewPolicyName");
       
   695 
       
   696     const TInt KMaxSequenceNumberStringLength = 32;
       
   697     _LIT(KSequenceNumberFormat, "(%d)");
       
   698     HBufC* sequenceNumberString = HBufC::NewLC(KMaxSequenceNumberStringLength);
       
   699     sequenceNumberString->Des().Format(KSequenceNumberFormat, aSequenceNumber);
       
   700 
       
   701     // New name string to be returned
       
   702     HBufC* retBuf(NULL);
       
   703     // Usage of Trim method in PinParser decreases the length by 2 items
       
   704     TInt spaceLeft = aOriginalPolicyName.MaxLength() - 2 - aOriginalPolicyName.Length();
       
   705     TInt sequenceNumberStringLength = sequenceNumberString->Length();
       
   706                                       
       
   707     if (sequenceNumberStringLength <= spaceLeft)
       
   708         {
       
   709         // There's enough free space for the sequence
       
   710         // number, so we can just add append it
       
   711         LOG_1(" Sequence number string: '%S'", &(*sequenceNumberString)); 
       
   712 
       
   713         // Determine final string length for dynamic allocation
       
   714         TInt len = aOriginalPolicyName.Length() + sequenceNumberString->Length();
       
   715         retBuf = HBufC::NewLC(len);
       
   716 
       
   717         // Construct the final name string
       
   718         TPtr16 ptr = retBuf->Des();
       
   719         ptr.Append(aOriginalPolicyName.Left(aOriginalPolicyName.Length()));
       
   720         ptr.Append(sequenceNumberString->Left(sequenceNumberString->Length()));
       
   721         }
       
   722     else
       
   723         {
       
   724         // There's not enough space for the sequence
       
   725         // number so we override the end of the policy
       
   726         // name with the sequence number
       
   727         TInt lengap = sequenceNumberStringLength - spaceLeft;
       
   728 
       
   729         // Determine final string length for dynamic allocation
       
   730         TInt len = aOriginalPolicyName.MaxLength();
       
   731         retBuf = HBufC::NewLC(len);
       
   732 
       
   733         // Construct the final name string
       
   734         TPtr16 ptr = retBuf->Des();
       
   735         ptr.Append(aOriginalPolicyName.Left(aOriginalPolicyName.Length() - lengap));
       
   736         ptr.Append(sequenceNumberString->Left(sequenceNumberString->Length()));
       
   737         }
       
   738 
       
   739     // Just pop, and delete the non-returned value explicitly
       
   740     CleanupStack::Pop(2); // retBuf, sequenceNumberString
       
   741     delete sequenceNumberString;
       
   742 
       
   743     LOG_("<- CPolicyStore::MakeNewPolicyName");
       
   744     return retBuf;
       
   745     }
       
   746 
       
   747 void CPolicyStore::ReplacePolicyL(const TVpnPolicyId& aPolicyToReplace, const TVpnPolicyId& aReplacingPolicy)
       
   748     {
       
   749     CFileInfoContainer* fileInfo = new (ELeave) CFileInfoContainer();
       
   750     CleanupStack::PushL(fileInfo);
       
   751 
       
   752     // Construct PIN and POL file names for
       
   753     // both the old and the new policy
       
   754 
       
   755     // Ownership is transferred
       
   756     fileInfo->iPinFileToReplace = iFileUtil.GetPinFileNameL(aPolicyToReplace);
       
   757     fileInfo->iPolFileToReplace = iFileUtil.GetPolFileNameL(aPolicyToReplace);
       
   758 
       
   759     fileInfo->iReplacingPinFile = iFileUtil.GetPinFileNameL(aReplacingPolicy);
       
   760     fileInfo->iReplacingPolFile = iFileUtil.GetPolFileNameL(aReplacingPolicy);
       
   761 
       
   762 
       
   763     // Store the name of the old policy (the original name)
       
   764     TPinParser* pinParser = new (ELeave) TPinParser(iFileUtil);
       
   765     CleanupStack::PushL(pinParser);
       
   766 
       
   767     pinParser->ParsePolicyDetailsL(*fileInfo->iPinFileToReplace, fileInfo->iOldPolicyDetails);
       
   768 
       
   769     // Delete the old PIN and POL files (note that this
       
   770     // policy is NOT deleted from the policy list)
       
   771     
       
   772     iFileUtil.DeleteFileL(*fileInfo->iPinFileToReplace);
       
   773     iFileUtil.DeleteFileL(*fileInfo->iPolFileToReplace);
       
   774 
       
   775     // Rename the new PIN and POL files such
       
   776     // that appear just as updated old files
       
   777     
       
   778     iFileUtil.MoveFileL(*fileInfo->iReplacingPinFile, *fileInfo->iPinFileToReplace);
       
   779     iFileUtil.MoveFileL(*fileInfo->iReplacingPolFile, *fileInfo->iPolFileToReplace);
       
   780 
       
   781     // Delete the new policy from the policy list
       
   782     // (it has been imported normally and thus appears in the list)
       
   783     
       
   784     DeletePolicyL(aReplacingPolicy);
       
   785 
       
   786     // Because of import, the updated policy has a sequence number in
       
   787     // its name, get rid of this by reverting to the original policy name
       
   788     
       
   789     pinParser->ParsePolicyDetailsL(*fileInfo->iPinFileToReplace, fileInfo->iNewPolicyDetails);
       
   790 
       
   791     fileInfo->iNewPolicyDetails.iName.Copy(fileInfo->iOldPolicyDetails.iName);
       
   792 
       
   793     HBufC* pinFileContent = pinParser->PolicyDetailsAsTextL(fileInfo->iNewPolicyDetails);
       
   794     CleanupStack::PushL(pinFileContent);
       
   795 
       
   796     iFileUtil.SaveFileDataL(*fileInfo->iPinFileToReplace, *pinFileContent);
       
   797 
       
   798     CleanupStack::PopAndDestroy(3); // pinFileContent, pinParser, fileInfo
       
   799     }
       
   800 
       
   801 // New methods to facilitate OMA DM based VPN policy management
       
   802 
       
   803 void CPolicyStore::AddNewPolicyL(TVpnPolicyDetails& aPolicyDetails, const TDesC8& aPolicyData)
       
   804     {
       
   805     
       
   806     LOG(Log::Printf(_L("-> CPolicyStore::AddNewPolicyL()")));
       
   807     
       
   808     // A non-empty policy name must be given
       
   809     if (aPolicyDetails.iName.Length() == 0)
       
   810         {
       
   811         User::Leave(KErrArgument);
       
   812         }
       
   813 
       
   814     // Policy data must be present
       
   815     if (aPolicyData.Length() == 0)
       
   816         {
       
   817         User::Leave(KErrArgument);
       
   818         }
       
   819 
       
   820     // If a (globally unique) policy ID
       
   821     // has not been specified, create it
       
   822     if (aPolicyDetails.iId.Length() == 0)
       
   823         {
       
   824         aPolicyDetails.iId.Copy(NewPolicyIdL());
       
   825         }
       
   826                            
       
   827     // If a policy with the same globally unique ID is already
       
   828     // present, then we cannot be adding a new policy
       
   829     if (PolicyIndex(aPolicyDetails.iId) != KUnfoundIndex)
       
   830         {
       
   831         User::Leave(KErrAlreadyExists);
       
   832         }
       
   833 
       
   834     DoEnsureUniquePolicyNameL(aPolicyDetails);
       
   835 
       
   836     LOG(Log::Printf(_L("Policy name ensured")));                
       
   837                         
       
   838     // Save policy details to the PIN file
       
   839     TPinParser* pinParser = new (ELeave) TPinParser(iFileUtil);
       
   840     CleanupStack::PushL(pinParser);    
       
   841 
       
   842     HBufC* pinFileContent = pinParser->PolicyDetailsAsTextL(aPolicyDetails);
       
   843     CleanupStack::PushL(pinFileContent);
       
   844 
       
   845     HBufC* pinFile = iFileUtil.GetPinFileNameLC(aPolicyDetails.iId);
       
   846 
       
   847     iFileUtil.SaveFileDataL(*pinFile, *pinFileContent);
       
   848 
       
   849     CleanupStack::PopAndDestroy(3); // pinFile, pinFileContent, pinParser
       
   850 
       
   851     LOG(Log::Printf(_L(" File data saved")));                
       
   852 
       
   853     // Save policy data to the POL file    
       
   854 
       
   855     HBufC* polFile = iFileUtil.GetPolFileNameLC(aPolicyDetails.iId);
       
   856 
       
   857     iFileUtil.SaveFileDataL(*polFile, aPolicyData);
       
   858     CleanupStack::PopAndDestroy(polFile);
       
   859     
       
   860     // Add the policy to the policy list
       
   861     AddPolicyL(aPolicyDetails.iId);
       
   862     LOG(Log::Printf(_L("<- CPolicyStore::AddNewPolicyL()")));
       
   863     }
       
   864 
       
   865 void CPolicyStore::UpdatePolicyDetailsL(TVpnPolicyDetails& aPolicyDetails)
       
   866     {
       
   867     TVpnPolicyId policyId;
       
   868     policyId.Copy(aPolicyDetails.iId);
       
   869 
       
   870     // The caller must specify the ID of the policy to be updated
       
   871     if (policyId.Length() == 0)
       
   872         {
       
   873         User::Leave(KErrArgument);
       
   874         }
       
   875     
       
   876     // A non-empty policy name must be specified, too
       
   877     if (aPolicyDetails.iName.Length() == 0)
       
   878         {
       
   879         User::Leave(KErrArgument);
       
   880         }
       
   881     
       
   882     // Make sure that the specified policy is present
       
   883     TInt policyIndex = PolicyIndex(policyId);
       
   884     if (policyIndex == KUnfoundIndex)
       
   885         {
       
   886         User::Leave(KVpnErrPolicyNotFound);
       
   887         }
       
   888 
       
   889     // See if the new name is different from the existing one
       
   890     if (iPolicyListAll->At(policyIndex).iName.CompareF(aPolicyDetails.iName) != 0)
       
   891         {
       
   892         // Make sure that the new name remains to be unique
       
   893         DoEnsureUniquePolicyNameL(aPolicyDetails);
       
   894         }
       
   895     
       
   896     // Save policy details to the PIN file
       
   897     TPinParser* pinParser = new (ELeave) TPinParser(iFileUtil);
       
   898     CleanupStack::PushL(pinParser);
       
   899     
       
   900     HBufC* pinFileContent = pinParser->PolicyDetailsAsTextL(aPolicyDetails);
       
   901     CleanupStack::PushL(pinFileContent);
       
   902 
       
   903     HBufC* pinFile = iFileUtil.GetPinFileNameLC(policyId);
       
   904     iFileUtil.SaveFileDataL(*pinFile, *pinFileContent);
       
   905 
       
   906     CleanupStack::PopAndDestroy(3); // pinFile, pinFileContent, pinParser
       
   907 
       
   908     // Update the policy name in the policy list as the name may have changed
       
   909     iPolicyListAll->At(policyIndex).iName.Copy(aPolicyDetails.iName);
       
   910 
       
   911     UpdateVisiblePolicyInfoL(aPolicyDetails);
       
   912     }
       
   913 
       
   914 void CPolicyStore::UpdateVisiblePolicyInfoL(const TVpnPolicyDetails& aPolicyDetails)
       
   915     {
       
   916     TVpnPolicyId policyId = aPolicyDetails.iId;
       
   917             
       
   918     // Find out whether the policy is hidden or visible
       
   919     TBool isHiddenPolicy = IsHiddenPolicyL(policyId);
       
   920             
       
   921     // See if the policy is in the list of visible ones
       
   922     TInt policyIndexVisible = PolicyIndexVisible(policyId);
       
   923 
       
   924     // If the policy is NOT in the visible list
       
   925     if (policyIndexVisible == KUnfoundIndex)
       
   926         {
       
   927         // If the policy is _no_longer_ hidden, add
       
   928         // it to the list of visible policies
       
   929         if (!isHiddenPolicy)
       
   930             {
       
   931             iPolicyListVisible->AppendL(static_cast<TVpnPolicyInfo>(aPolicyDetails));
       
   932             }
       
   933         }
       
   934     else // The policy IS in the visible list
       
   935         {
       
   936         // If the policy is _now_ hidden, remove
       
   937         // it from the list of visible ones
       
   938         if (isHiddenPolicy)
       
   939             {
       
   940             iPolicyListVisible->Delete(policyIndexVisible);
       
   941             iPolicyListVisible->Compress();
       
   942             }
       
   943         else
       
   944             { 
       
   945             // Otherwise update the policy name of the policy in the
       
   946             // list of visible policies as the name may have changed
       
   947             iPolicyListVisible->At(policyIndexVisible).iName.Copy(aPolicyDetails.iName);
       
   948             }
       
   949         }
       
   950     }
       
   951 
       
   952 void CPolicyStore::UpdatePolicyDataL(
       
   953     const TVpnPolicyId& aPolicyId, const TDesC8& aPolicyData)
       
   954     {
       
   955     // The caller must specify the ID of the policy to be updated
       
   956     if (aPolicyId.Length() == 0)
       
   957         {
       
   958         User::Leave(KErrArgument);
       
   959         }
       
   960 
       
   961     // Policy data must be present
       
   962     if (aPolicyData.Length() == 0)
       
   963         {
       
   964         User::Leave(KErrArgument);
       
   965         }
       
   966     
       
   967     // Make sure that the policy is present
       
   968     if (PolicyIndex(aPolicyId) == KUnfoundIndex)
       
   969         {
       
   970         User::Leave(KVpnErrPolicyNotFound);
       
   971         }
       
   972 
       
   973     // Save policy data to the POL file
       
   974 
       
   975     HBufC* polFile = iFileUtil.GetPolFileNameLC(aPolicyId);
       
   976     iFileUtil.SaveFileDataL(*polFile, aPolicyData);
       
   977     CleanupStack::PopAndDestroy(polFile);
       
   978     }
       
   979 
       
   980 TBool CPolicyStore::IsHiddenPolicyL(const TVpnPolicyId& aPolicyId)
       
   981     {
       
   982     TVpnPolicyDetails* policyDetails = new (ELeave) TVpnPolicyDetails();
       
   983     CleanupStack::PushL(policyDetails);
       
   984         
       
   985     TPinParser* pinParser = new (ELeave) TPinParser(iFileUtil);
       
   986     CleanupStack::PushL(pinParser);
       
   987 
       
   988     HBufC* pinFile = iFileUtil.GetPinFileNameLC(aPolicyId);
       
   989 
       
   990     pinParser->ParsePolicyDetailsL(*pinFile, *policyDetails);
       
   991     CleanupStack::PopAndDestroy(2); // pinFile, pinParser
       
   992     
       
   993     // A policy is marked as hidden if it's description 
       
   994     // field contains the "hidden indicator" string
       
   995     if (policyDetails->iDescription.FindF(KHiddenPolicyIndicator) != 
       
   996         KErrNotFound)
       
   997         {
       
   998         CleanupStack::PopAndDestroy(); // policyDetails
       
   999         return ETrue;
       
  1000         }
       
  1001     else
       
  1002         {
       
  1003         CleanupStack::PopAndDestroy(); // policyDetails
       
  1004         return EFalse;
       
  1005         }
       
  1006     }