--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vpnengine/vpnmanager/src/policyimporter.cpp Thu Dec 17 09:14:51 2009 +0200
@@ -0,0 +1,1154 @@
+/*
+* Copyright (c) 2003-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Policy importer
+*
+*/
+
+
+
+#include "policyimporter.h"
+#include "vpnapiservant.h"
+#include "fileutil.h"
+#include "policypatcher.h"
+#include "policystore.h"
+#include "vpnclientuids.h"
+#include "vpnmanagerserverdefs.h"
+#include "ikepolparser.h"
+#include "pkiutil.h"
+#include "cmmanagerutils.h"
+#include "log_r6.h"
+
+#include <f32file.h>
+#include <x509cert.h>
+
+const TInt KDefaultKeySize(1024);
+
+enum TImportState
+ {
+ EStateBeginPolicyImport = 1,
+ EStateImportCaCert,
+ EStateAfterImportCaCert,
+ EStateImportPeerCert,
+ EStateAfterImportPeerCert,
+ EStateImportUserPrivKey,
+ EStateAfterImportUserPrivKey,
+ EStateAttachCertificate,
+ EStateAfterAttachCertificate,
+ EStateImportPinAndPol,
+ EStateCreateVpnDestination,
+ EStateEndPolicyImport
+ };
+
+CPolicyImporter* CPolicyImporter::NewL(const RMessage2& aMessage, CVpnApiServant& aVpnApiServant,
+ CPolicyStore& aPolicyStore, RFs& aFs)
+ {
+ LOG_("-> CPolicyImporter::NewL()");
+ CPolicyImporter* self = new (ELeave) CPolicyImporter(aMessage, aVpnApiServant, aPolicyStore, aFs);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(); // self
+ LOG_("<- CPolicyImporter::NewL()");
+ return self;
+ }
+
+CPolicyImporter* CPolicyImporter::NewL(TRequestStatus& aStatus, CVpnApiServant& aVpnApiServant,
+ CPolicyStore& aPolicyStore, RFs& aFs)
+ {
+ LOG_("-> CPolicyImporter::NewL()");
+ CPolicyImporter* self = new (ELeave) CPolicyImporter(aStatus, aVpnApiServant, aPolicyStore, aFs);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(); // self
+ LOG_("<- CPolicyImporter::NewL()");
+ return self;
+ }
+
+CPolicyImporter::CPolicyImporter(const RMessage2& aMessage, CVpnApiServant& aVpnApiServant,
+ CPolicyStore& aPolicyStore, RFs& aFs) :
+ CActive(0), iMessage(aMessage), iVpnApiServant(aVpnApiServant),
+ iPolicyStore(aPolicyStore), iFs(aFs), iFileUtil(aFs)
+ {
+ }
+
+CPolicyImporter::CPolicyImporter(TRequestStatus& aStatus, CVpnApiServant& aVpnApiServant,
+ CPolicyStore& aPolicyStore, RFs& aFs) :
+ CActive(0), iExtStatus(&aStatus), iVpnApiServant(aVpnApiServant),
+ iPolicyStore(aPolicyStore), iFs(aFs), iFileUtil(aFs)
+ {
+ }
+
+void CPolicyImporter::ConstructL()
+ {
+ CActiveScheduler::Add(this);
+ User::LeaveIfError(iPkiService.Connect());
+ }
+
+CPolicyImporter::~CPolicyImporter()
+ {
+ LOG_("-> CPolicyImporter::~CPolicyImporter()");
+ Cancel();
+ iPkiService.Close();
+
+ delete iPolicyIdList;
+
+ delete iCurrIkeDataArray;
+
+ delete iCurrCaCertList;
+ delete iCurrPeerCertList;
+ delete iCurrUserPrivKeyList;
+ delete iCurrUserCertList;
+ delete iCurrOtherCaCertList;
+
+ delete iCertFileData;
+ delete iKeyFileData;
+ LOG_("<- CPolicyImporter::~CPolicyImporter()");
+ }
+
+TInt CPolicyImporter::RunError(TInt aError)
+ {
+ LOG_EVENT_2B(R_VPN_MSG_POLICY_INSTALL_FAIL, iNewPolicyId, NULL,
+ aError, iImportSinglePolicy);
+
+ ImportComplete(aError);
+ return KErrNone;
+ }
+
+void CPolicyImporter::RunL()
+ {
+ ChangeStateL();
+ }
+
+void CPolicyImporter::DoCancel()
+ {
+ CancelOngoingOperation();
+ if (iImportSinglePolicy)
+ {
+ User::RequestComplete(iExtStatus, KErrCancel);
+ }
+ else
+ {
+ iMessage.Complete(KErrCancel);
+ }
+ CleanImportDirectory();
+ }
+
+void CPolicyImporter::GotoState(TInt aState)
+ {
+ LOG_1("-> CPolicyImporter::GotoState() STATE %d", aState);
+ SetNextState(aState);
+ SetActive();
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ LOG_("<- CPolicyImporter::GotoState()");
+ }
+
+void CPolicyImporter::SetCurrState(TInt aState)
+ {
+ iCurrState = aState;
+ }
+
+void CPolicyImporter::SetNextState(TInt aState)
+ {
+ iNextState = aState;
+ }
+
+TInt CPolicyImporter::CurrState()
+ {
+ return iCurrState;
+ }
+
+TInt CPolicyImporter::NextState()
+ {
+ return iNextState;
+ }
+
+void CPolicyImporter::ChangeStateL()
+ {
+ switch (NextState())
+ {
+ case EStateBeginPolicyImport:
+ StateBeginPolicyImportL();
+ break;
+
+ case EStateImportCaCert:
+ StateImportCaCertL();
+ break;
+
+ case EStateAfterImportCaCert:
+ StateAfterImportCaCertL();
+ break;
+
+ case EStateImportPeerCert:
+ StateImportPeerCertL();
+ break;
+
+ case EStateAfterImportPeerCert:
+ StateAfterImportPeerCertL();
+ break;
+
+ case EStateImportUserPrivKey:
+ StateImportUserPrivKeyL();
+ break;
+
+ case EStateAfterImportUserPrivKey:
+ StateAfterImportUserPrivKeyL();
+ break;
+
+ case EStateAttachCertificate:
+ StateAttachCertificateL();
+ break;
+
+ case EStateAfterAttachCertificate:
+ StateAfterAttachCertificateL();
+ break;
+
+ case EStateImportPinAndPol:
+ StateImportPinAndPolL();
+ break;
+
+ case EStateCreateVpnDestination:
+ StateCreateVpnDestinationL();
+ break;
+
+ case EStateEndPolicyImport:
+ StateEndPolicyImportL();
+ break;
+
+ default:
+ User::Panic(KVpnManagerServer, EInvalidImportState);
+ break;
+ }
+ }
+
+void CPolicyImporter::CancelOngoingOperation()
+ {
+ switch (CurrState())
+ {
+ case EStateImportCaCert:
+ case EStateImportPeerCert:
+ case EStateImportUserPrivKey:
+ case EStateAttachCertificate:
+ iPkiService.CancelPendingOperation();
+ iPkiService.Finalize(iPkiOpContext);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+void CPolicyImporter::ImportComplete(TInt aReturnValue)
+ {
+ LOG_("-> CPolicyImporter::ImportComplete()");
+ if (iImportSinglePolicy)
+ {
+ User::RequestComplete(iExtStatus, aReturnValue);
+ }
+ else
+ {
+ iMessage.Complete(aReturnValue);
+ }
+ CleanImportDirectory();
+ iVpnApiServant.PolicyImportComplete();
+ LOG_("<- CPolicyImporter::ImportComplete()");
+ }
+
+void CPolicyImporter::ImportPolicyL(const TDesC& aDir)
+ {
+ LOG_("-> CPolicyImporter::ImportPolicyL()");
+ iImportSinglePolicy = EFalse;
+ iNewPolicyId = &iPolicyId;
+ DoImportPolicyL(aDir);
+ LOG_("<- CPolicyImporter::ImportPolicyL()");
+ }
+
+void CPolicyImporter::ImportSinglePolicyL(const TDesC& aDir, TVpnPolicyId& aNewPolicyId)
+ {
+ LOG_("-> CPolicyImporter::ImportSinglePolicyL()");
+ iImportSinglePolicy = ETrue;
+ iNewPolicyId = &aNewPolicyId;
+ DoImportPolicyL(aDir);
+ LOG_("<- CPolicyImporter::ImportSinglePolicyL()");
+ }
+
+void CPolicyImporter::DoImportPolicyL(const TDesC& aDir)
+ {
+ LOG_("-> CPolicyImporter::DoImportPolicyL()");
+ iImportDir.Copy(aDir);
+ iCurrPolicyIdIndex = -1;
+
+ BuildPolicyIdListL();
+
+ if (iPolicyIdList->Count() == 0)
+ {
+ ImportComplete(KErrNone);
+ return;
+ }
+
+ if (iImportSinglePolicy && iPolicyIdList->Count() != 1)
+ {
+ // We're supposed to import a single policy
+ // only but the import directory contains
+ // multiple policies...
+ ImportComplete(KErrArgument);
+ return;
+ }
+
+ // All is well, so begin import
+ GotoState(EStateBeginPolicyImport);
+ LOG_("<- CPolicyImporter::DoImportPolicyL()");
+ }
+
+void CPolicyImporter::StateBeginPolicyImportL()
+ {
+ SetCurrState(EStateBeginPolicyImport);
+
+ iCurrPolicyIdIndex++;
+
+ if (iCurrPolicyIdIndex == iPolicyIdList->Count())
+ {
+ ImportComplete(KErrNone);
+ return;
+ }
+
+ iCurrPolicyId.Copy(iPolicyIdList->At(iCurrPolicyIdIndex));
+
+ ParseIkeDataL();
+
+ BuildCaCertListL();
+ iCurrCaCertIndex = -1;
+
+ BuildPeerCertListL();
+ iCurrPeerCertIndex = -1;
+
+ BuildUserPrivKeyAndUserCertListL();
+ iCurrUserPrivKeyIndex = -1;
+ iCurrUserCertIndex = -1;
+
+ BuildOtherCaCertListL();
+ iCurrOtherCaCertIndex=-1;
+ GotoState(EStateImportCaCert);
+ }
+
+void CPolicyImporter::StateImportCaCertL()
+ {
+ LOG_("CPolicyImporter::StateImportCaCertL() entry");
+ SetCurrState(EStateImportCaCert);
+
+ iCurrCaCertIndex++;
+
+ if (iCurrCaCertIndex == iCurrCaCertList->Count())
+ {
+ GotoState(EStateImportPeerCert);
+ LOG_("CPolicyImporter::StateImportCaCertL() exit (all CA certs imported)");
+ return;
+ }
+
+ delete iCertFileData;
+ iCertFileData = NULL;
+ iCertFileData = iFileUtil.LoadFileDataL(iCurrCaCertList->At(iCurrCaCertIndex));
+
+ iPkiService.StoreCertificateL(EPKICACertificate, KDefaultKeySize, EPKIRSA, *iCertFileData,
+ &iPkiOpContext, iStatus);
+
+ SetNextState(EStateAfterImportCaCert);
+ SetActive();
+ LOG_("CPolicyImporter::StateImportCaCertL() exit");
+ }
+
+void CPolicyImporter::StateAfterImportCaCertL()
+ {
+ SetCurrState(EStateAfterImportCaCert);
+
+ iPkiService.Finalize(iPkiOpContext);
+
+
+ if (iStatus == KErrArgument)
+ {
+ User::Leave(KVpnErrInvalidCaCertFile);
+ }
+ else if (iStatus != KErrNone)
+ {
+ User::Leave(iStatus.Int());
+ }
+
+ // Set VPN trusted
+ CX509Certificate* tempCert = CX509Certificate::NewLC(*iCertFileData);
+ RArray<TUid> appArray;
+ CleanupClosePushL(appArray);
+ appArray.AppendL(TUid::Uid(KUidVpnManager));
+
+ const TPtrC8* serialNumber = tempCert->DataElementEncoding(
+ CX509Certificate::ESerialNumber);
+ const TPtrC8* issuername = tempCert->DataElementEncoding(
+ CX509Certificate::EIssuerName);
+
+ iPkiService.SetApplicabilityL(
+ *issuername,
+ *serialNumber,
+ appArray);
+
+ CleanupStack::PopAndDestroy(2); // appArray, tempCert
+
+ // Handle the next certificate, if present
+ GotoState(EStateImportCaCert);
+ }
+
+void CPolicyImporter::StateImportPeerCertL()
+ {
+ LOG_("CPolicyImporter::StateImportOtherCaCertL() entry");
+ SetCurrState(EStateImportPeerCert);
+
+ iCurrOtherCaCertIndex++;
+
+ if (iCurrOtherCaCertIndex == iCurrOtherCaCertList->Count())
+ {
+ GotoState(EStateImportUserPrivKey);
+ LOG_("CPolicyImporter::StateImportOtherCaCertL() exit (all intermediate CAs imported)");
+ return;
+ }
+
+ delete iCertFileData;
+ iCertFileData = NULL;
+ iCertFileData = iFileUtil.LoadFileDataL(iCurrOtherCaCertList->At(iCurrOtherCaCertIndex));
+ CIkeData* data = iCurrIkeDataArray->At(iCurrIkeDataIndex);
+ TPkiServiceStoreType storeType = GetStoreTypeL(data);
+ iPkiService.SetStoreType(storeType);
+
+ iPkiService.StoreCertificateL(EPKICACertificate, KDefaultKeySize, EPKIRSA, *iCertFileData,
+ &iPkiOpContext, iStatus);
+
+ SetNextState(EStateAfterImportPeerCert);
+ SetActive();
+ LOG_("CPolicyImporter::StateImportOtherCACertL() exit");
+ }
+
+void CPolicyImporter::StateAfterImportPeerCertL()
+ {
+ SetCurrState(EStateAfterImportPeerCert);
+
+ iPkiService.Finalize(iPkiOpContext);
+
+ if (iStatus != KErrNone)
+ {
+ User::Leave(iStatus.Int());
+ }
+
+ // Handle the next certificate, if present
+ GotoState(EStateImportPeerCert);
+ }
+
+TPkiServiceStoreType CPolicyImporter::GetStoreTypeL(CIkeData* aData)
+ {
+ TPkiServiceStoreType ret(EPkiStoreTypeAny);
+ if (aData->iClientCertType)
+ {
+ HBufC8* storename = aData->iClientCertType->GetAsciiDataL();
+ CleanupStack::PushL(storename);
+ LOG(Log::Printf(_L8("CPolicyImporter::BuildPeerCertListL() Store type defined in policy: %S\n"), &(*storename)));
+
+ if (storename->Compare(_L8("DEVICE")) == 0)
+ {
+ LOG_("CPolicyImporter::BuildPeerCertListL() Policy uses DEVICE store\n");
+ ret = EPkiStoreTypeDevice;
+ }
+ else
+ {
+ LOG_("CPolicyImporter::BuildPeerCertListL() Policy uses USER store\n");
+ ret = EPkiStoreTypeUser;
+ }
+
+ CleanupStack::PopAndDestroy(storename);
+ }
+ else
+ {
+ LOG_("CPolicyImporter::GetStoreType() No store type specified in policy");
+ }
+ return ret;
+ }
+void CPolicyImporter::StateImportUserPrivKeyL()
+ {
+ LOG_("CPolicyImporter::StateImportUserPrivKeyL() entry");
+ SetCurrState(EStateImportUserPrivKey);
+
+ iCurrUserPrivKeyIndex++;
+
+ if (iCurrUserPrivKeyIndex == iCurrUserPrivKeyList->Count())
+ {
+ GotoState(EStateImportPinAndPol);
+ LOG_("CPolicyImporter::StateImportUserPrivKeyL() exit (all keys imported)");
+ return;
+ }
+
+ delete iKeyFileData;
+ iKeyFileData = NULL;
+ iKeyFileData = iFileUtil.LoadFileDataL(iCurrUserPrivKeyList->At(iCurrUserPrivKeyIndex));
+ CIkeData* data = iCurrIkeDataArray->At(iCurrIkeDataIndex);
+ TPkiServiceStoreType storeType = GetStoreTypeL(data);
+ iPkiService.SetStoreType(storeType);
+
+ iPkiService.StoreKeypair(iCurrKeyId, *iKeyFileData, iStatus);
+
+ SetNextState(EStateAfterImportUserPrivKey);
+ SetActive();
+ LOG_("CPolicyImporter::StateImportUserPrivKeyL() exit");
+ }
+
+void CPolicyImporter::StateAfterImportUserPrivKeyL()
+ {
+ SetCurrState(EStateAfterImportUserPrivKey);
+
+ if (iStatus == KErrArgument || iStatus == KErrNotSupported)
+ {
+ User::Leave(KVpnErrInvalidUserPrivKeyFile);
+ }
+ else if (iStatus != KErrNone)
+ {
+ User::Leave(iStatus.Int());
+ }
+
+ // Attach user certificates to the imported private key
+ iCurrIkeDataIndex = -1;
+ GotoState(EStateAttachCertificate);
+ }
+
+void CPolicyImporter::StateAttachCertificateL()
+ {
+ LOG_("CPolicyImporter::StateAttachCertificateL() entry");
+ SetCurrState(EStateAttachCertificate);
+
+ iCurrIkeDataIndex++;
+
+ if (iCurrIkeDataIndex == iCurrIkeDataArray->Count())
+ {
+ // Import the next private key, if present
+ GotoState(EStateImportUserPrivKey);
+ return;
+ }
+
+ CIkeData* ikeData = iCurrIkeDataArray->At(iCurrIkeDataIndex);
+ HBufC* fileName(NULL);
+ TPkiServiceStoreType storeType = GetStoreTypeL(ikeData);
+ iPkiService.SetStoreType(storeType);
+
+ fileName = iFileUtil.MakeFileName(iImportDir, ikeData->iPrivKey.iData).AllocLC();
+
+ if (fileName->CompareF(iCurrUserPrivKeyList->At(iCurrUserPrivKeyIndex)) == 0)
+ {
+ CleanupStack::PopAndDestroy(fileName);
+ fileName = NULL;
+
+ fileName = iFileUtil.MakeFileName(iImportDir, ikeData->iOwnCert.iData).AllocLC();
+
+ delete iCertFileData;
+ iCertFileData = NULL;
+ iCertFileData = iFileUtil.LoadFileDataL(*fileName);
+
+ iPkiService.AttachCertificateL(iCurrKeyId, KDefaultKeySize, EPKIRSA, *iCertFileData,
+ &iPkiOpContext, iStatus);
+
+ SetNextState(EStateAfterAttachCertificate);
+ SetActive();
+ }
+ else
+ {
+ // Attach the next certificate, if present
+ GotoState(EStateAttachCertificate);
+ }
+ CleanupStack::PopAndDestroy(fileName); // fileName
+ LOG_("CPolicyImporter::StateAttachCertificateL() exit");
+ }
+
+void CPolicyImporter::StateAfterAttachCertificateL()
+ {
+ SetCurrState(EStateAfterAttachCertificate);
+
+ iPkiService.Finalize(iPkiOpContext);
+
+ if (iStatus == KErrArgument)
+ {
+ User::Leave(KVpnErrInvalidUserCertFile);
+ }
+ else if (iStatus != KErrNone)
+ {
+ User::Leave(iStatus.Int());
+ }
+
+ // Attach the next certificate, if present
+ GotoState(EStateAttachCertificate);
+ }
+
+void CPolicyImporter::StateImportPinAndPolL()
+ {
+ LOG_("-> CPolicyImporter::StateImportPinAndPolL()");
+ SetCurrState(EStateImportPinAndPol);
+
+ HBufC* pinFile = iFileUtil.MakeFileNameLC(iImportDir, iCurrPolicyId, KPinFileExt);
+ HBufC* polFile = iFileUtil.MakeFileNameLC(iImportDir, iCurrPolicyId, KPolFileExt);
+
+ if (!iFileUtil.FileExists(*pinFile))
+ {
+ LOG_("<- CPolicyImporter::StateImportPinAndPolL() LEAVE: KVpnErrNoPolicyInfoFile");
+ User::Leave(KVpnErrNoPolicyInfoFile);
+ }
+ else if (!iFileUtil.FileExists(*polFile))
+ {
+ LOG_("<- CPolicyImporter::StateImportPinAndPolL() LEAVE: KVpnErrNoPolicyFile");
+ User::Leave(KVpnErrNoPolicyFile);
+ }
+ else
+ {
+ PatchPolicyCaCertInfoL(*polFile);
+
+ iPolicyStore.ImportPolicyL(*pinFile, *polFile, iNewPolicyId);
+
+ //iImportSinglePolicy is used when policy is installed via
+ //OMA DM or ACU. If the policy is installed from .vpn file
+ //the iImportSinglePolicy is not used.
+ //The VPN destination is only created in .vpn case.
+ if (iImportSinglePolicy)
+ {
+ GotoState(EStateEndPolicyImport);
+ }
+ else
+ {
+ GotoState(EStateCreateVpnDestination);
+ }
+ }
+ CleanupStack::PopAndDestroy(2); // polfile, pinfile
+ LOG_("<- CPolicyImporter::StateImportPinAndPolL()");
+ }
+
+void CPolicyImporter::StateCreateVpnDestinationL()
+ {
+ LOG_("-> CPolicyImporter::StateCreateVpnDestinationL()");
+ SetCurrState(EStateCreateVpnDestination);
+
+ //Gets the IAP name from policy name
+ TVpnPolicyInfo* policyInfo = new (ELeave) TVpnPolicyInfo;
+ CleanupDeletePushL(policyInfo);
+
+ User::LeaveIfError(iPolicyStore.GetPolicyInfo(*iNewPolicyId, *policyInfo));
+
+ CmManagerUtils::CreateVPNConnectionMethodToIntranetL(*policyInfo,
+ *(iVpnApiServant.iEventLogger));
+
+ CleanupStack::PopAndDestroy(); //policyInfo
+ GotoState(EStateEndPolicyImport);
+
+ LOG_("<- CPolicyImporter::StateCreateVpnDestinationL()");
+ }
+
+void CPolicyImporter::StateEndPolicyImportL()
+ {
+ LOG_("-> CPolicyImporter::StateEndPolicyImportL()");
+
+ STACK_LEFT;
+
+ SetCurrState(EStateEndPolicyImport);
+
+ // Delete the files that were just imported from the import/install directory
+
+ HBufC* fileFilter = iFileUtil.MakeFileNameLC(iImportDir, iCurrPolicyId, KAllFilesPat);
+ iFileUtil.DeleteFilesL(*fileFilter);
+
+ CleanupStack::PopAndDestroy(); // fileFilter
+
+ LOG_EVENT_2B(R_VPN_MSG_INSTALLED_POLICY_FILE, iNewPolicyId, NULL, 0, iImportSinglePolicy);
+
+ GotoState(EStateBeginPolicyImport);
+ LOG_("<- CPolicyImporter::StateEndPolicyImportL()");
+ }
+
+void CPolicyImporter::BuildPolicyIdListL()
+ {
+ delete iPolicyIdList;
+ iPolicyIdList = NULL;
+ iPolicyIdList = new (ELeave) CArrayFixFlat<TExtVpnPolicyId>(2);
+
+ TFindFile* fileFinder = new (ELeave) TFindFile(iFs);
+ CleanupStack::PushL(fileFinder);
+
+ CDir* fileList;
+
+ TInt ret = fileFinder->FindWildByDir(KPinFilePat, iImportDir, fileList);
+
+ if (ret == KErrNone)
+ {
+ CleanupStack::PushL(fileList);
+
+ for (TInt i = 0; i < fileList->Count(); i++)
+ {
+ TParse* fileNameParser = new (ELeave) TParse();
+ CleanupStack::PushL(fileNameParser);
+
+ fileNameParser->Set((*fileList)[i].iName, NULL, NULL);
+
+ TExtVpnPolicyId policyId;
+ policyId.Copy(fileNameParser->Name());
+
+ iPolicyIdList->AppendL(policyId);
+
+ CleanupStack::PopAndDestroy(); // fileNameParser
+ }
+ CleanupStack::PopAndDestroy(); // fileList
+ }
+ CleanupStack::PopAndDestroy(); // fileFinder
+ }
+
+void CPolicyImporter::BuildCaCertListL()
+ {
+ LOG_("-> CPolicyImporter::BuildCaCertListL()");
+ delete iCurrCaCertList;
+ iCurrCaCertList = NULL;
+ iCurrCaCertList = new (ELeave) CArrayFixFlat<TFileName>(2);
+
+ TFileName *fileName = new (ELeave) TFileName;
+ CleanupStack::PushL(fileName);
+
+ LOG_("Pre-for");
+ for (TInt i = 0; i < iCurrIkeDataArray->Count(); i++)
+ {
+ LOG_("For start");
+ CIkeData* ikeData = iCurrIkeDataArray->At(i);
+ fileName->Zero();
+
+ if (ikeData->iCAList)
+ {
+ LOG_("CAlist found");
+ for (TInt j = 0; j < ikeData->iCAList->Count(); j++)
+ {
+ LOG_("CA iter start");
+ if (ikeData->iCAList->At(j)->iFormat == BIN_CERT)
+ {
+ LOG_("Bin cert found");
+ *fileName = iFileUtil.MakeFileName(iImportDir, ikeData->iCAList->At(j)->iData);
+ if (!iFileUtil.FileExists(*fileName))
+ {
+ LOG_("<- CPolicyImporter::BuildCaCertListL() LEAVE (KVpnErrCaCertFileMissing)");
+ User::Leave(KVpnErrInvalidCaCertFile);
+ }
+ //Makes sure every file name is appended only once.
+ AppendIfNotFoundL( iCurrCaCertList, fileName );
+ }
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy(); //fileName
+ LOG_("<- CPolicyImporter::BuildCaCertListL()");
+ }
+
+
+void CPolicyImporter::BuildPeerCertListL()
+ {
+ LOG(Log::Printf(_L8("-> CPolicyImporter::BuildPeerCertListL()\n")));
+ delete iCurrPeerCertList;
+ iCurrPeerCertList = NULL;
+ iCurrPeerCertList = new (ELeave) CArrayFixFlat<TFileName>(2);
+
+ TFileName *fileName = new (ELeave) TFileName;
+ CleanupStack::PushL(fileName);
+
+ for (TInt i = 0; i < iCurrIkeDataArray->Count(); i++)
+ {
+ CIkeData* ikeData = iCurrIkeDataArray->At(i);
+ fileName->Zero();
+
+ if (ikeData->iPeerCert.iData.Length() > 0 &&
+ ikeData->iPeerCert.iFormat == BIN_CERT)
+ {
+ *fileName = iFileUtil.MakeFileName(iImportDir, ikeData->iPeerCert.iData);
+ if (!iFileUtil.FileExists(*fileName))
+ {
+ User::Leave(KVpnErrPeerCertFileMissing);
+ }
+ AppendIfNotFoundL( iCurrPeerCertList, fileName );
+ }
+ }
+
+ CleanupStack::PopAndDestroy(); //fileName
+ LOG_("<- CPolicyImporter::BuildPeerCertListL()");
+ }
+
+
+void CPolicyImporter::BuildUserPrivKeyAndUserCertListL()
+ {
+ LOG_("-> CPolicyImporter::BuildUserPrivKeyAndUserCertListL()");
+ delete iCurrUserPrivKeyList;
+ iCurrUserPrivKeyList = NULL;
+ iCurrUserPrivKeyList = new (ELeave) CArrayFixFlat<TFileName>(2);
+
+ delete iCurrUserCertList;
+ iCurrUserCertList = NULL;
+ iCurrUserCertList = new (ELeave) CArrayFixFlat<TFileName>(2);
+
+ TFileName *fileName = new (ELeave) TFileName;
+ CleanupStack::PushL(fileName);
+
+
+ for (TInt i = 0; i < iCurrIkeDataArray->Count(); i++)
+ {
+ CIkeData* ikeData = iCurrIkeDataArray->At(i);
+ fileName->Zero();
+
+ if (ikeData->iOwnCert.iData.Length() > 0 &&
+ ikeData->iOwnCert.iFormat == BIN_CERT)
+ {
+ //First check that defined user cert is found and if so
+ //add the file name to the list
+
+ *fileName = iFileUtil.MakeFileName(iImportDir, ikeData->iOwnCert.iData);
+ if (!iFileUtil.FileExists(*fileName))
+ {
+ User::Leave(KVpnErrInvalidUserCertFile);
+ }
+ AppendIfNotFoundL( iCurrUserCertList, fileName );
+
+ //After the user cert is found check that the assosiated private key
+ //is found.
+ if (ikeData->iPrivKey.iData.Length() > 0 &&
+ ikeData->iPrivKey.iFormat == BIN_CERT)
+ {
+ fileName->Zero();
+ *fileName = iFileUtil.MakeFileName(iImportDir, ikeData->iPrivKey.iData);
+ if (!iFileUtil.FileExists(*fileName))
+ {
+ User::Leave(KVpnErrInvalidUserPrivKeyFile);
+ }
+ AppendIfNotFoundL( iCurrUserPrivKeyList, fileName );
+ }
+ else
+ {
+ User::Leave(KVpnErrInvalidPolicyFile);
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy(); //fileName
+ LOG_("<- CPolicyImporter::BuildUserPrivKeyAndUserCertListL()");
+ }
+
+void CPolicyImporter::BuildOtherCaCertListL()
+ {
+ LOG(Log::Printf(_L8("-> CPolicyImporter::BuildOtherCACertListL()\n")));
+ delete iCurrOtherCaCertList;
+ iCurrOtherCaCertList = NULL;
+ iCurrOtherCaCertList = new (ELeave) CArrayFixFlat<TFileName>(2);
+ TFileName *fileName = new (ELeave) TFileName;
+ CleanupStack::PushL(fileName);
+ TFileName *totalPath= new (ELeave) TFileName;
+ CleanupStack::PushL(totalPath);
+ CDir* dirList=NULL;
+ _LIT(KFileSpec, "*ca-?.*er");
+ *totalPath=iImportDir;
+ totalPath->Append(KFileSpec);
+
+
+ User::LeaveIfError(
+ iFs.GetDir(*totalPath,
+ KEntryAttMaskSupported,
+ ESortByName, dirList));
+ CleanupStack::PushL(dirList);
+ if ( dirList->Count()>1 )
+ {
+ for (TInt i=0;i<dirList->Count();i++)
+ {
+ *fileName = (*dirList)[i].iName;
+ *totalPath = iImportDir;
+ totalPath->Append(*fileName);
+ AppendIfNotFoundL(iCurrOtherCaCertList, totalPath);
+ }
+ }
+ CleanupStack::PopAndDestroy(dirList);
+ CleanupStack::PopAndDestroy(totalPath);
+
+ CleanupStack::PopAndDestroy(); //fileName
+ LOG_("<- CPolicyImporter::BuildOtherCaCertListL()");
+ }
+
+void CPolicyImporter::ParseIkeDataL()
+ {
+ LOG_("-> CPolicyImporter::ParseIkeDataL()");
+
+ HBufC* polFile = iFileUtil.MakeFileNameLC(iImportDir, iCurrPolicyId, KPolFileExt);
+
+ if (!iFileUtil.FileExists(*polFile))
+ {
+ LOG_("<- CPolicyImporter::ParseIkeDataL() LEAVE (KVpnErrNoPolicyFile)");
+ User::Leave(KVpnErrNoPolicyFile);
+ }
+
+ HBufC8* fileData = iFileUtil.LoadFileDataL(*polFile);
+ CleanupStack::PushL(fileData);
+
+ HBufC* fileData16 = HBufC::NewLC(fileData->Length());
+
+ fileData16->Des().Copy(*fileData);
+
+ delete iCurrIkeDataArray;
+ iCurrIkeDataArray = NULL;
+ iCurrIkeDataArray = CIkeDataArray::NewL(1);
+
+ TIkeParser* ikeParser = new (ELeave) TIkeParser(*fileData16);
+ CleanupStack::PushL(ikeParser);
+ ikeParser->ParseIKESectionsL(iCurrIkeDataArray);
+
+ CleanupStack::PopAndDestroy(4); // ikeParser, fileData16, fileData, polFile
+ LOG_("<- CPolicyImporter::ParseIkeDataL()");
+ }
+
+
+void CPolicyImporter::PatchPolicyCaCertInfoL(const TFileName& aPolicyFile)
+ {
+ LOG_("-> CPolicyImporter::PatchPolicyCaCertInfoL()");
+ HBufC8* policyData = iFileUtil.LoadFileDataL(aPolicyFile);
+ CleanupStack::PushL(policyData);
+
+ CPolicyPatchInfoList* patchInfoList = BuildPolicyPatchInfoListL();
+ CleanupStack::PushL(patchInfoList);
+
+ CPolicyPatcher* patcher = CPolicyPatcher::NewL();
+ CleanupStack::PushL(patcher);
+
+ HBufC8* patchedPolicyData = patcher->PatchPolicyL(*policyData, patchInfoList);
+ CleanupStack::PushL(patchedPolicyData);
+
+ iFileUtil.SaveFileDataL(aPolicyFile, *patchedPolicyData);
+
+ CleanupStack::PopAndDestroy(4); // patchedPolicyData, patcher, patchInfoList, policyData
+ LOG_("<- CPolicyImporter::PatchPolicyCaCertInfoL()");
+ }
+
+CPolicyPatchInfoList* CPolicyImporter::BuildPolicyPatchInfoListL()
+ {
+ LOG_("-> CPolicyImporter::BuildPolicyPatchInfoListL()");
+ CPolicyPatchInfoList* patchInfoList = new (ELeave) CPolicyPatchInfoList(2);
+ CleanupStack::PushL(patchInfoList);
+ HBufC8* subjectName;
+ // First, append the CA certs to patch list...
+ for (TInt i = 0; i < iCurrCaCertList->Count(); i++)
+ {
+
+ CPolicyPatchInfo* patchInfo = new (ELeave) CPolicyPatchInfo();
+ CleanupStack::PushL(patchInfo);
+
+ TParse fileNameParser;
+ fileNameParser.Set(iCurrCaCertList->At(i), NULL, NULL);
+
+ patchInfo->iCertFileName.Copy(fileNameParser.NameAndExt());
+ subjectName = CertSubjectNameL(iCurrCaCertList->At(i));
+ CleanupStack::PushL(subjectName);
+ if ( iCurrOtherCaCertList->Count()>1 && iCurrCaCertList->Count()==1 ) //if other than basic CA certificate exists
+ {
+ // Set original intermediate CA untrusted. .
+ HBufC8* certData = iFileUtil.LoadFileDataL(iCurrCaCertList->At(0));
+ CleanupStack::PushL(certData);
+ CX509Certificate* tempCert = CX509Certificate::NewLC(*certData);
+ RArray<TUid> appArray;
+ CleanupClosePushL(appArray);
+ const TPtrC8* serialNumber = tempCert->DataElementEncoding(
+ CX509Certificate::ESerialNumber);
+ const TPtrC8* issuername = tempCert->DataElementEncoding(
+ CX509Certificate::EIssuerName);
+
+ iPkiService.SetApplicabilityL(
+ *issuername,
+ *serialNumber,
+ appArray);
+
+ CleanupStack::PopAndDestroy(3); // appArray, tempcert
+
+ //get CA from chain
+ TFileName rootCAFile=GetCAFromFileListL(*subjectName, iCurrOtherCaCertList);
+ CleanupStack::PopAndDestroy(subjectName);
+ subjectName=NULL;
+ subjectName = CertSubjectNameL(rootCAFile);
+ CleanupStack::PushL(subjectName);
+
+ //Set highest CA as trusted
+ certData = iFileUtil.LoadFileDataL(rootCAFile);
+ CleanupStack::PushL(certData);
+ tempCert = CX509Certificate::NewLC(*certData);
+ CleanupClosePushL(appArray);
+ appArray.AppendL(TUid::Uid(KUidVpnManager));
+ serialNumber = tempCert->DataElementEncoding(
+ CX509Certificate::ESerialNumber);
+ issuername = tempCert->DataElementEncoding(
+ CX509Certificate::EIssuerName);
+
+ iPkiService.SetApplicabilityL(
+ *issuername,
+ *serialNumber,
+ appArray);
+
+ CleanupStack::PopAndDestroy(3); // appArray, tempcert, certData
+ }
+ patchInfo->SetCertSubjectNameL(*subjectName);
+
+ patchInfoList->AppendL(patchInfo);
+ CleanupStack::PopAndDestroy(subjectName);
+ subjectName=NULL;
+ CleanupStack::Pop(patchInfo); // patcInfo (now owned by the list)
+ }
+
+ // ... then, append also the user certificates.
+ for (TInt i = 0; i < iCurrUserCertList->Count(); i++)
+ {
+ TInt keySize = 0;
+ HBufC8* subjectName = CertInfoL(iCurrUserCertList->At(i), keySize);
+ CleanupStack::PushL(subjectName);
+
+ CPolicyPatchInfo* patchInfo = new (ELeave) CPolicyPatchInfo();
+ CleanupStack::PushL(patchInfo);
+
+ TParse fileNameParser;
+ fileNameParser.Set(iCurrUserCertList->At(i), NULL, NULL);
+
+ patchInfo->iCertFileName.Copy(fileNameParser.NameAndExt());
+ patchInfo->SetCertSubjectNameL(*subjectName);
+ patchInfo->SetUserCertKeyLen(keySize);
+
+ patchInfoList->AppendL(patchInfo);
+
+ CleanupStack::Pop(); // patchInfo (now owned by the list)
+ CleanupStack::PopAndDestroy(); // subjectName
+ }
+
+ CleanupStack::Pop(); // patchInfoList, ownership transferred
+
+ LOG_("<- CPolicyImporter::BuildPolicyPatchInfoListL()");
+ return patchInfoList;
+ }
+
+HBufC8* CPolicyImporter::CertSubjectNameL(const TFileName& aCertFile)
+ {
+ TInt keySize = KDoNotGetKeySize;
+ return CertInfoL(aCertFile,keySize);
+ }
+
+void CPolicyImporter::CleanImportDirectory()
+ {
+ LOG_("-> CPolicyImporter::CleanImportDirectory()");
+
+ TRAP_IGNORE(
+ {
+ HBufC* fileFilter = iFileUtil.MakeFileNameLC(iImportDir, KNullDesC, KAllFilesPat);
+ iFileUtil.DeleteFilesL(*fileFilter);
+ CleanupStack::PopAndDestroy();
+ });
+
+ LOG_("<- CPolicyImporter::CleanImportDirectory()");
+ }
+
+void CPolicyImporter::AppendIfNotFoundL(CArrayFixFlat<TFileName>* aList,
+ TFileName* aFileName)
+ {
+ ASSERT(aList && aFileName);
+
+ TKeyArrayFix arrayKey(0, ECmpFolded);
+ TInt position;
+ if ( aList->FindIsq( *aFileName, arrayKey, position ) )
+ {
+ aList->AppendL( *aFileName );
+ }
+ }
+
+HBufC8* CPolicyImporter::CertInfoL(const TFileName& aCertFile, TInt& aKeySize)
+ {
+ HBufC8* certData = iFileUtil.LoadFileDataL(aCertFile);
+ CleanupStack::PushL(certData);
+
+ HBufC* subjectName = PkiUtil::CertSubjectNameL(*certData);
+ CleanupStack::PushL(subjectName);
+
+ HBufC8* subjectName8 = HBufC8::NewL(subjectName->Length());
+ subjectName8->Des().Copy(*subjectName);
+
+ if(KDoNotGetKeySize != aKeySize)
+ {
+ aKeySize = PkiUtil::CertKeySizeL(*certData);
+ }
+
+ CleanupStack::PopAndDestroy(2); // subjectName, certData
+
+ return subjectName8;
+ }
+
+HBufC8* CPolicyImporter::CertIssuerL(const TFileName& aCertFile)
+ {
+ HBufC8* certData = iFileUtil.LoadFileDataL(aCertFile);
+ CleanupStack::PushL(certData);
+
+ HBufC* issuerName = PkiUtil::CertIssuerNameL(*certData);
+ CleanupStack::PushL(issuerName);
+
+ HBufC8* issuerName8 = HBufC8::NewL(issuerName->Length());
+ issuerName8->Des().Copy(*issuerName);
+
+ CleanupStack::PopAndDestroy(2); // subjectName, certData
+
+ return issuerName8;
+ }
+
+TFileName CPolicyImporter::GetCAFromFileListL(const TDesC8& aCertSubjectName, CArrayFixFlat<TFileName>* aCertFileArray)
+ {
+ TFileName rootCa;
+ TInt currCaIndex=0;
+ TInt currIndex=1;
+ TInt keySize = 0;
+ for ( TInt i=0; i<aCertFileArray->Count(); i++)
+ {
+ HBufC8* certSubjectName = CertInfoL(aCertFileArray->At(i), keySize);
+ CleanupStack::PushL(certSubjectName);
+ if ( certSubjectName->Compare(aCertSubjectName) == 0)
+ currCaIndex=i;
+ CleanupStack::PopAndDestroy(certSubjectName);
+ certSubjectName=NULL;
+ }
+
+
+ while ( currIndex< aCertFileArray->Count())
+ {
+ HBufC8* issuerName = CertIssuerL(aCertFileArray->At(currCaIndex));
+ CleanupStack::PushL(issuerName);
+ HBufC8* subjectName = CertInfoL(aCertFileArray->At(currCaIndex), keySize);
+ CleanupStack::PushL(subjectName);
+
+ for (TInt i=0; i<aCertFileArray->Count();i++)
+ {
+ HBufC8* certSubjectName = CertInfoL(aCertFileArray->At(i), keySize);
+ CleanupStack::PushL(certSubjectName);
+ if ( certSubjectName->Compare(*issuerName)==0 )
+ {
+ currCaIndex=i;
+ CleanupStack::PopAndDestroy(certSubjectName);
+ certSubjectName=NULL;
+ break;
+ }
+ CleanupStack::PopAndDestroy(certSubjectName);
+ certSubjectName=NULL;
+ }
+
+ CleanupStack::PopAndDestroy(subjectName);
+ subjectName=NULL;
+ CleanupStack::PopAndDestroy(issuerName);
+ issuerName=NULL;
+ currIndex++;
+ }
+
+ return aCertFileArray->At(currCaIndex);
+
+ }
+/***/