--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/terminalsecurity/SCP/SCPServer/src/SCPServer.cpp Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,2915 @@
+/*
+* Copyright (c) 2000 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: Implementation of terminalsecurity components
+*
+*/
+
+
+// INCLUDE FILES
+#include <utf.h>
+#include <e32svr.h>
+#include <e32math.h>
+#include <gsmerror.h>
+
+#include "SCPServer.h"
+#include "SCPSession.h"
+
+#ifdef SCP_USE_POLICY_ENGINE
+#include <PolicyEngineClient.h>
+#include <PolicyEngineXACML.h>
+#include <RequestContext.h>
+#include "DMUtilObserver.h"
+#include "SCPParamDBController.h"
+#endif // SCP_USE_POLICY_ENGINE
+
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS
+#include "SCPPluginManager.h"
+#include "SCPPluginEventHandler.h"
+#include <SCPParamObject.h>
+#include "SCP_IDs.h"
+// For Central Repository
+#include <centralrepository.h>
+#include "SCPCodePrivateCRKeys.h"
+#include "SCPLockCode.h"
+#include <TerminalControl3rdPartyAPI.h>
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS
+
+#include <mmtsy_names.h>
+
+#include "SCPDebug.h"
+#include <featmgr.h>
+// For Device encryption
+#include <DevEncEngineConstants.h>
+#include <DevEncSession.h>
+
+// ==================== LOCAL FUNCTIONS ====================
+
+// ---------------------------------------------------------
+// PanicServer Panics the server thread
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+GLDEF_C void PanicServer(TSCPServPanic aPanic)
+ {
+ _LIT( KTxtServerPanic,"SCP Server panic" );
+ User::Panic( KTxtServerPanic, aPanic );
+ }
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CSession2* CSCPServer::CSCPServer()
+// C++ default constructor
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+CSCPServer::CSCPServer(TInt aPriority)
+ : CPolicyServer( aPriority, CSCPServerPolicy ),
+ iConfiguration( &iRfs ),
+ iALPeriodRep( NULL ),
+ iShutdownTimer( NULL ),
+ iOverrideForCleanup(EFalse) {
+ Dprint( (_L("--> CSCPServer::CSCPServer()") ));
+
+ Dprint( (_L("<-- CSCPServer::CSCPServer()") ));
+ }
+
+
+
+// ---------------------------------------------------------
+// CSession2* CSCPServer::ConstructL()
+// Symbian 2nd phase constructor
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+void CSCPServer::ConstructL()
+ {
+ Dprint(_L("[CSCPServer]-> ConstructL() >>>"));
+
+ TRAPD( errf, FeatureManager::InitializeLibL() );
+ if( errf != KErrNone )
+ {
+ User::Leave(errf);
+ }
+
+ StartL( KSCPServerName );
+
+ User::LeaveIfError( iRfs.Connect() );
+
+ iConfiguration.Initialize();
+
+ // Assign default config flag
+ iConfiguration.iConfigFlag = KSCPConfigUnknown;
+
+ // Assign the default codes
+ iConfiguration.iSecCode.Zero();
+ iConfiguration.iSecCode.Append( KSCPDefaultSecCode );
+
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS
+if(FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+{
+ // Reset code block parameters
+ iConfiguration.iFailedAttempts = 0;
+ iConfiguration.iBlockedAtTime = KSCPNotBlocked;
+
+ iPluginEventHandler = CSCPPluginEventHandler::NewL( &iRfs );
+
+ iPluginManager = CSCPPluginManager::NewL( this );
+
+ // Hash the default code
+ TBuf<KSCPMaxHashLength> hashBuf;
+ hashBuf.Zero();
+
+ HBufC* codeHBuf = HBufC::NewLC( KSCPPasscodeMaxLength + 1 );
+ TPtr codeBuf = codeHBuf->Des();
+ codeBuf.Zero();
+
+ codeBuf.Copy( KSCPDefaultEnchSecCode );
+ iPluginEventHandler->HashInput( codeBuf, hashBuf );
+
+ iConfiguration.iEnhSecCode.Zero();
+ iConfiguration.iEnhSecCode.Append( hashBuf );
+
+ CleanupStack::PopAndDestroy( codeHBuf );
+}
+//#endif
+
+ // Assign the default max timeout
+ iConfiguration.iMaxTimeout = KSCPDefaultMaxTO;
+ iConfiguration.iBlockedInOOS = 0;
+
+ // Read the configuration, overwriting the default values
+ TInt ret = KErrNone;
+ TRAPD( err, ret = iConfiguration.ReadSetupL() );
+ if ( ( err != KErrNone ) || ( ret != KErrNone ) )
+ {
+ Dprint( (_L("CSCPServer::ConstructL(): ERROR reading the \
+ configuration file: %d"), err ));
+ }
+ else
+ {
+ Dprint( (_L("CSCPServer::ConstructL(): Configration read OK") ));
+ }
+
+ Dprint( (_L("CSCPServer::ConstructL(): Connecting to CenRep") ));
+ iALPeriodRep = CRepository::NewL( KCRUidSecuritySettings );
+
+ // Check for factory settings
+ CheckIfRfsPerformedL();
+ Dprint(_L("[CSCPServer]-> ConstructL() <<< "));
+ }
+
+
+
+
+// ---------------------------------------------------------
+// CSession2* CSCPServer::NewL()
+// Static constructor.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+CSCPServer* CSCPServer::NewL()
+ {
+ Dprint( (_L("--> CSCPServer::NewL()") ));
+
+ CSCPServer *pS = new (ELeave) CSCPServer( EPriority );
+
+ CleanupStack::PushL( pS );
+ pS->ConstructL();
+ CleanupStack::Pop( pS );
+
+ Dprint( (_L("<-- CSCPServer::NewL()") ));
+ return pS;
+ }
+
+
+
+// ---------------------------------------------------------
+// CSession2* CSCPServer::~CSCPServer ()
+// Destructor
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+CSCPServer::~CSCPServer()
+ {
+ Dprint( (_L("--> CSCPServer::~CSCPServer()") ));
+
+ TRAPD( err, iConfiguration.WriteSetupL() );
+ if ( err != KErrNone )
+ {
+ Dprint( (_L("CSCPServer::~CSCPServer(): ERROR writing the \
+ configuration file: %d"), err ));
+ }
+
+ delete iALPeriodRep;
+ iALPeriodRep = NULL;
+
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS
+if(FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+{
+
+ delete iPluginManager;
+ iPluginManager = NULL;
+
+ delete iPluginEventHandler;
+ iPluginEventHandler = NULL;
+}
+FeatureManager::UnInitializeLib();
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS
+
+ if ( iPhone.SubSessionHandle() )
+ {
+ iPhone.Close();
+ }
+
+ if ( iTelServ.Handle() )
+ {
+ iTelServ.Close();
+ }
+
+ if ( iRfs.Handle() )
+ {
+ iRfs.Close();
+ }
+
+ Dprint( (_L("<-- CSCPServer::~CSCPServer()") ));
+ }
+
+
+
+// ---------------------------------------------------------
+// CSession2* CSCPServer::NewSessionL (const TVersion &aVersion, const RMessage2& aMsg )
+// Checks the version and creates a new session if it matches the server version.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+CSession2* CSCPServer::NewSessionL (const TVersion &aVersion,
+ const RMessage2& aMsg ) const
+ {
+ Dprint( (_L("--> CSCPServer::NewSessionL()") ));
+ (void)aMsg;
+
+ // Check we're the right version
+ TVersion v( KSCPServMajorVersionNumber, KSCPServMinorVersionNumber,
+ KSCPServBuildVersionNumber );
+
+ if ( !User::QueryVersionSupported(v, aVersion) )
+ User::Leave( KErrNotSupported );
+
+ Dprint( (_L("<-- CSCPServer::NewSessionL()") ));
+
+ return CSCPSession::NewL( (CSCPServer&)( *this ) );
+ }
+
+
+
+// ---------------------------------------------------------
+// TInt CSCPServer::ThreadFunctionStage2()
+// Constructs the active scheduler and the server object, and
+// runs the server.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TInt CSCPServer::ThreadFunctionStage2L()
+ {
+ Dprint( (_L("--> CSCPServer::ThreadFunctionStage2()") ));
+
+ // Naming the server thread after the server helps to debug panics
+ User::LeaveIfError( User::RenameThread( KSCPServerName ) );
+
+ // Construct the active scheduler
+ CActiveScheduler* activeScheduler = new (ELeave) CActiveScheduler;
+ CleanupStack::PushL(activeScheduler);
+
+ // Install active scheduler
+ // We don't need to check whether an active scheduler is already installed
+ // as this is a new thread, so there won't be one
+ CActiveScheduler::Install( activeScheduler );
+
+ // Construct our server
+ CSCPServer* server = CSCPServer::NewL();
+ CleanupStack::PushL( server );
+
+ RProcess::Rendezvous(KErrNone);
+
+ // Start handling requests
+ Dprint( (_L("CSCPServer: Server started") ));
+ CActiveScheduler::Start();
+
+ CleanupStack::PopAndDestroy( server );
+ CleanupStack::PopAndDestroy( activeScheduler );
+
+ Dprint( (_L("<-- CSCPServer::ThreadFunctionStage2()") ));
+ return KErrNone;
+ }
+
+
+
+// ---------------------------------------------------------
+// TInt CSCPServer::ThreadFunction( TAny* )
+// First-stage server entry point, creates the cleanup stack,
+// and calls the actual server worker function.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TInt CSCPServer::ThreadFunction(TAny* /*aNone*/)
+ {
+ Dprint( (_L("--> CSCPServer::ThreadFunction()") ));
+
+ __UHEAP_MARK;
+
+ CTrapCleanup* cleanupStack = CTrapCleanup::New();
+ if ( !cleanupStack )
+ {
+ PanicServer( ECreateTrapCleanup );
+ }
+
+ TRAPD( err, ThreadFunctionStage2L() );
+ if ( err != KErrNone )
+ {
+ PanicServer( ESvrStartServer );
+ }
+
+ delete cleanupStack;
+ cleanupStack = NULL;
+
+ __UHEAP_MARKEND;
+
+ Dprint( (_L("<-- CSCPServer::ThreadFunction()") ));
+ return KErrNone;
+ }
+
+
+// ---------------------------------------------------------
+// void CSCPServer::GetEtelHandlesL()
+// Opens the handles to the Etel API, if not open, and copies
+// their addresses to the given pointers, if available.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+void CSCPServer::GetEtelHandlesL( RTelServer** aTelServ, RMobilePhone** aPhone )
+ {
+ if ( !iTelServ.Handle() )
+ {
+ // Connect to Etel
+ User::LeaveIfError( iTelServ.Connect() );
+
+ Dprint( (_L("CSCPServer::GetEtelHandlesL(): TelServ connected OK") ));
+ }
+
+ if ( !iPhone.SubSessionHandle() )
+ {
+ // Load the phone module
+ TInt err = iTelServ.LoadPhoneModule( KMmTsyModuleName );
+ if ( err != KErrAlreadyExists )
+ {
+ User::LeaveIfError( err );
+ }
+ Dprint( (_L("CSCPServer::GetEtelHandlesL(): LoadPhoneModule OK") ));
+
+ // Open the multimode TSY
+ User::LeaveIfError( iPhone.Open( iTelServ, KMmTsyPhoneName ) );
+
+ Dprint( (_L("CSCPServer::GetEtelHandlesL(): MM-Phone connected OK") ));
+ }
+
+ if ( aTelServ )
+ {
+ *aTelServ = &iTelServ;
+ }
+
+ if ( aPhone )
+ {
+ *aPhone = &iPhone;
+ }
+ }
+
+
+// ---------------------------------------------------------
+// TInt CSCPServer::GetCode( TDes& aCode )
+// Writes the stored ISA code to aCode
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TInt CSCPServer::GetCode( TDes& aCode )
+ {
+ Dprint( (_L("--> CSCPServer::GetCode()") ));
+
+ aCode.Zero();
+ aCode.Copy( iConfiguration.iSecCode );
+
+ Dprint( (_L("<-- CSCPServer::GetCode()") ));
+ return KErrNone;
+ }
+
+
+
+// ---------------------------------------------------------
+// TInt CSCPServer::StoreCode( TDes& aCode )
+// Sets the stored ISA code to aCode and saves it to flash
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TInt CSCPServer::StoreCode( TDes& aCode )
+ {
+ Dprint( (_L("--> CSCPServer::StoreCode()") ));
+
+ TInt ret = KErrNone;
+
+ iConfiguration.iSecCode.Zero();
+ iConfiguration.iSecCode.Copy( aCode );
+
+ // Unset the invalid configuration flag
+ iConfiguration.iConfigFlag = KSCPConfigOK;
+
+ // The code has changed, write the new value instantly to flash
+ TRAPD( err, iConfiguration.WriteSetupL() );
+ if ( err != KErrNone )
+ {
+ Dprint( (_L("CSCPServer::~CSCPServer(): ERROR writing the configuration\
+ file: %d"), err ));
+ ret = err;
+ }
+
+ Dprint( (_L("<-- CSCPServer::StoreCode(): %d"), ret ));
+
+ return ret;
+ }
+
+
+
+// ---------------------------------------------------------
+// CSCPServer::ChangeISACodeL()
+// Initializes the TSY and calls the function to change
+// the ISA-side code. Automatically uses the old code stored
+// on the server.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+void CSCPServer::ChangeISACodeL( RMobilePhone::TMobilePassword& aNewPassword )
+ {
+ Dprint( (_L("--> CSCPServer::ChangeISACodeL()") ));
+
+ RMobilePhone::TMobilePassword oldPassword;
+ TInt ret;
+
+ // Check the given code
+ if ( !IsValidISACode( aNewPassword ) )
+ {
+ Dprint( (_L("CSCPServer::ChangeISACodeL(): ERROR:\
+ Invalid code format") ));
+ User::Leave( KErrArgument );
+ }
+
+ // No access to the ISA side in emulator
+ GetEtelHandlesL();
+
+ // Fetch the stored ISA password from the server
+
+ ret = GetCode( oldPassword );
+ if ( ret != KErrNone )
+ {
+ Dprint( (_L("CSCPServer::ChangeISACodeL(): ERROR:\
+ Failed to get stored code") ));
+ User::Leave( ret );
+ }
+
+ TRequestStatus status = KErrNone;
+
+#ifndef __WINS__
+ // No access to the ISA side in emulator, for WINS the call always succeeds
+
+ RMobilePhone::TMobilePhonePasswordChangeV1 changeInfo;
+ changeInfo.iOldPassword = oldPassword;
+ changeInfo.iNewPassword = aNewPassword;
+
+ RMobilePhone::TMobilePhoneSecurityCode securityCode =
+ RMobilePhone::ESecurityCodePhonePassword;
+
+ Dprint( (_L("CSCPServer::ChangeISACodeL(): Trying to change\
+ the code, values %s, %s"), oldPassword.PtrZ(), aNewPassword.PtrZ() ));
+
+ iPhone.ChangeSecurityCode(status, securityCode, changeInfo );
+
+ // This is a quick call, just wait here
+ User::WaitForRequest( status );
+
+#endif // WINS
+ ret = status.Int();
+
+ if ( ret == KErrNone )
+ {
+ Dprint( (_L("CSCPServer::ChangeISACodeL(): Code change OK") ));
+
+ // Update the stored code in the server
+ if ( StoreCode( aNewPassword ) != KErrNone )
+ {
+ Dprint( (_L("CSCPServer::ChangeISACodeL():\
+ Failed to store the new code!") ));
+ ret = KErrGeneral;
+ }
+ }
+ else
+ {
+ Dprint( (_L("CSCPServer::ChangeISACodeL(): FAILED:\
+ ChangeSecurityCode returned %d"), ret ));
+ }
+
+ User::LeaveIfError( ret );
+ Dprint( (_L("<-- CSCPServer::ChangeISACodeL()") ));
+ }
+
+
+
+// ---------------------------------------------------------
+// TInt CSCPServer::CheckIfRfsPerformedL()
+// Checks if RFS has been run from the DMUtil server.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+void CSCPServer::CheckIfRfsPerformedL()
+ {
+ Dprint( (_L("--> CSCPServer::CheckIfRfsPerformedL()") ));
+
+ TBool resetServer = EFalse;
+
+#ifdef SCP_USE_POLICY_ENGINE
+ Dprint( (_L("--> CSCPServer::CheckIfRfsPerformedL() : checking if Rfs performed") ));
+ TRAPD(err,TDMUtilPassiveObserver::IsRFSPerformedL());
+ if ( err == 1 )
+ {
+ resetServer = ETrue;
+ }
+ else if ( err == 0)
+ {
+ Dprint( (_L("--> CSCPServer::CheckIfRfsPerformedL() : Rfs is not performed") ));
+ }
+ else
+ {
+ Dprint( (_L("--> CSCPServer::CheckIfRfsPerformedL() : Leave occured. Ignore it.") ));
+ }
+#endif // SCP_USE_POLICY_ENGINE
+
+ if ( resetServer )
+ {
+ Dprint( (_L("CSCPServer::CheckIfRfsPerformedL(): Rfs performed, resetting parameters") ));
+
+ // Reset max. period
+ iConfiguration.iMaxTimeout = 0;
+
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS
+if(FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+{
+ // Reset the common plugin parameter storage
+ TRAPD( err, iPluginEventHandler->ResetConfigurationL() );
+ if ( err != KErrNone )
+ {
+ Dprint( (_L("CSCPServer::CheckIfRfsPerformedL(): ERROR resetting the plugin\
+ configuration: %d"), err ));
+ }
+
+ // Reset the plugin's private storage
+ CSCPParamObject* inParams = CSCPParamObject::NewL();
+ CleanupStack::PushL( inParams );
+
+ inParams->Set( KSCPParamContext, KSCPContextRfs );
+
+ CSCPParamObject* reply =
+ iPluginManager->PostEvent( KSCPEventReset, *inParams );
+ CleanupStack::PopAndDestroy( inParams );
+
+ // Ignore the reply, no plugin should request any actions
+ if ( reply != NULL )
+ {
+ delete reply;
+ }
+}
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS
+
+ }
+
+ Dprint( (_L("<-- CSCPServer::CheckIfRfsPerformedL()") ));
+ }
+
+
+
+
+// ---------------------------------------------------------
+// void CSCPServer::ValidateConfigurationL()
+// Checks if the correct ISA code is stored on the server.
+// This method is used to counter the 3-button format function
+// available on some devices.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+void CSCPServer::ValidateConfigurationL( TInt aMode )
+ {
+ Dprint( (_L("--> CSCPServer::ValidateConfigurationL()") ));
+
+ if ( iConfiguration.iConfigFlag == KSCPConfigOK )
+ {
+ // The configuration has already been checked, exit
+ Dprint( (_L("CSCPServer::ValidateConfigurationL(): Configuration is non-default.") ));
+ User::Leave( KErrNone );
+ }
+ else if ( aMode == KSCPInitial )
+ {
+ // Return here, must be checked by complete mode
+ User::Leave( KErrAccessDenied );
+ }
+
+ RMobilePhone::TMobilePassword storedCode;
+ storedCode.Zero();
+
+ User::LeaveIfError( GetCode( storedCode ) );
+ TInt hashedISAcode;
+ TSCPSecCode hashedCode;
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS
+if(FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+{
+ /*TInt*/ hashedISAcode = HashISACode( iConfiguration.iEnhSecCode );
+ // TSCPSecCode hashedCode;
+ hashedCode.Zero();
+ hashedCode.AppendNum( hashedISAcode );
+}
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS
+
+ Dprint( (_L("CSCPServer::ValidateConfigurationL(): Checking code: %s"), storedCode.PtrZ() ));
+
+ // Check that the ISA code is stored correctly
+ TRAPD( err, CheckISACodeL( storedCode ) );
+ if ( err == KErrNone )
+ {
+ iConfiguration.iConfigFlag = KSCPConfigOK;
+ }
+ else if ( err == KErrAccessDenied )
+ {
+ iConfiguration.iConfigFlag = KSCPConfigInvalid;
+ }
+ else if ( err == KErrLocked )
+ {
+ Dprint( (_L("CSCPServer::ValidateConfigurationL(): ISA code locked.") ));
+ }
+ else
+ {
+ Dprint( (_L("CSCPServer::ValidateConfigurationL(): ERROR in validation.") ));
+ }
+
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS
+if(FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+{
+ if ( err == KErrNone )
+ {
+ // Check that the codes are in-sync with each other. Especially the default ISA code must
+ // be changed according to the default enhanced code.
+ if ( storedCode.Compare( hashedCode ) != 0 )
+ {
+ Dprint( (_L("CSCPServer::ValidateConfigurationL(): Correct ISA code stored.\
+ Changing ISA code to match enhanced code => %d"), hashedISAcode ));
+
+ storedCode.Copy( hashedCode );
+ // Change the ISA code to match the hashed code
+ ChangeISACodeL( storedCode );
+ }
+ }
+ else if ( ( err == KErrAccessDenied ) && ( storedCode.Compare( hashedCode ) != 0 ) )
+ {
+ // Try again with the hashed code
+ TRAP( err, CheckISACodeL( hashedCode ) );
+
+ if ( err == KErrNone )
+ {
+ Dprint( (_L("CSCPServer::ValidateConfigurationL(): Hashed code is correct.\
+ Storing hashed code(%d)"), hashedISAcode ));
+
+ if ( StoreCode( hashedCode ) == KErrNone )
+ {
+ iConfiguration.iConfigFlag = KSCPConfigOK;
+ }
+ }
+ }
+}
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS
+
+ TRAPD( err2, iConfiguration.WriteSetupL() );
+ if ( err2 != KErrNone )
+ {
+ Dprint( (_L("CSCPServer::ValidateConfigurationL(): WARNING: failed to write configuration\
+ : %d"), err2 ));
+ }
+
+ User::LeaveIfError( err );
+
+ Dprint( (_L("<-- CSCPServer::ValidateConfigurationL()") ));
+ }
+
+
+
+
+// ---------------------------------------------------------
+// void CSCPServer::CheckISACodeL( )
+// Verifies the given ISA code.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+void CSCPServer::CheckISACodeL( RMobilePhone::TMobilePassword aCode )
+ {
+ TInt ret = KErrNone;
+
+#ifdef __WINS__
+
+ (void)aCode;
+
+#endif // __WINS__
+
+ RMobilePhone::TMobilePhoneSecurityCode secCodeType;
+ secCodeType = RMobilePhone::ESecurityCodePhonePassword;
+
+ RMobilePhone::TMobilePassword required_fourth;
+
+ TRequestStatus status = KRequestPending;
+
+ GetEtelHandlesL();
+
+#ifndef __WINS__ // We cannot check the code in WINS, always return KErrNone.
+
+ iPhone.VerifySecurityCode( status, secCodeType, aCode, required_fourth );
+
+ // This should be quick, wait here
+ User::WaitForRequest( status );
+
+ ret = status.Int();
+
+#endif // !__WINS__
+
+ if ( ret == KErrNone )
+ {
+ // Code OK
+ Dprint( (_L("CSCPServer::CheckISACodeL(): ISA code OK") ));
+ iConfiguration.iBlockedInOOS = 0;
+ }
+ else
+ {
+ if ( ( ret == KErrAccessDenied ) || ( ret == KErrGsm0707IncorrectPassword ) )
+ {
+ Dprint( (_L("CSCPServer::CheckISACodeL(): ISA code NOT OK") ));
+ if (iConfiguration.iBlockedInOOS == 1)
+ {
+ iConfiguration.iBlockedInOOS = 0;
+ Dprint( (_L("CSCPServer::CheckISACodeL():iBlockedInOOS = 0, KErrAccessDenied") ));
+ }
+ ret = KErrAccessDenied;
+ }
+ else if ( ( ret == KErrGsmSSPasswordAttemptsViolation ) || ( ret == KErrLocked ) )
+ {
+ Dprint( (_L("CSCPServer::CheckISACodeL(): ISA code BLOCKED") ));
+ if (ret==KErrGsmSSPasswordAttemptsViolation)
+ {
+ Dprint( (_L("CSCPServer::CheckISACodeL(): KErrGsmSSPasswordAttemptsViolation") ));
+ }
+ else
+ {
+ Dprint( (_L("CSCPServer::CheckISACodeL(): KErrLocked") ));
+ }
+ ret = KErrLocked;
+ if (iConfiguration.iBlockedInOOS == 0)
+ {
+ iConfiguration.iBlockedInOOS = 1;
+ Dprint( (_L("CSCPServer::CheckISACodeL():iBlockedInOOS = 1, KSCPErrCodeBlockStarted") ));
+ ret = KSCPErrCodeBlockStarted;
+ }
+ }
+ else
+ {
+ Dprint( (_L("CSCPServer::CheckISACodeL(): ERROR reply checking ISA code: %d"),
+ status.Int() ));
+ }
+ }
+ TRAPD( err, iConfiguration.WriteSetupL() );
+ if ( err != KErrNone )
+ {
+ Dprint( (_L("CSCPServer::StoreEnhCode(): WARNING:\
+ failed to write configuration: %d"), err ));
+ }
+
+ User::LeaveIfError( ret );
+ }
+
+
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS
+
+// ---------------------------------------------------------
+// CSCPServer::HashISACode()
+// Creates a 5-digit ISA code from the given MD5 digest.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TInt CSCPServer::HashISACode( TDes& aHashBuf )
+ {
+ // aHashBuf must be a MD5 hash digest
+ if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+ {
+ return KErrNotSupported;
+ }
+ if ( aHashBuf.Length() < KSCPMD5HashLen )
+ {
+ PanicServer( EBadHashDigest );
+ }
+
+ // Compute the hash sum as four 32-bit integers.
+ TInt64 hashSum = *(reinterpret_cast<TInt32*>(&aHashBuf[0])) +
+ *(reinterpret_cast<TInt32*>(&aHashBuf[4])) +
+ *(reinterpret_cast<TInt32*>(&aHashBuf[8])) +
+ *(reinterpret_cast<TInt32*>(&aHashBuf[12]));
+
+ // Create a five-digit security code from this number
+ TInt ISAcode = ( hashSum % 90000 ) + 10000;
+ Dprint( (_L("CSCPServer::HashISACode(): Hashed ISA code is %d"), ISAcode ));
+
+ return ISAcode;
+ }
+
+
+// ---------------------------------------------------------
+// TInt CSCPServer::StoreEnhCode( TDes& aCode )
+// Sets the stored enhanced code to aCode and saves it to flash
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TInt CSCPServer::StoreEnhCode( TDes& aCode, TSCPSecCode* aNewDOSCode /*=NULL*/)
+ {
+
+ if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+ {
+ return KErrNotSupported;
+ }
+ Dprint( (_L("CSCPServer::StoreEnhCode()") ));
+
+ // Hash the code and save it
+ TBuf<KSCPMaxHashLength> hashBuf;
+ hashBuf.Zero();
+ iPluginEventHandler->HashInput( aCode, hashBuf );
+
+ TInt ISAcode = HashISACode( hashBuf );
+
+ RMobilePhone::TMobilePassword newCode;
+ newCode.Zero();
+ newCode.AppendNum( ISAcode );
+
+ // Change the ISA code
+ TRAPD( err, ChangeISACodeL( newCode ) );
+
+ if ( err == KErrNone )
+ {
+ iConfiguration.iEnhSecCode.Zero();
+ iConfiguration.iEnhSecCode.Copy( hashBuf );
+
+ if ( aNewDOSCode != NULL )
+ {
+ // Copy the updated DOS code
+ (*aNewDOSCode).Copy( newCode );
+ }
+
+ TRAPD( err, iConfiguration.WriteSetupL() );
+ if ( err != KErrNone )
+ {
+ Dprint( (_L("CSCPServer::StoreEnhCode(): WARNING:\
+ failed to write configuration: %d"), err ));
+
+ }
+ else
+ {
+ /* Get the very first character of the new lock code and set the default input mode of the
+ lock code query on the basis of the first character. */
+ ch = aCode[0];
+
+ CRepository* repository = NULL;
+ def_mode = ch.IsDigit() ? 0 : 1;
+ TRAPD(err, repository = CRepository::NewL( KCRUidSCPParameters ));
+ if (err == KErrNone)
+ {
+ err = repository->Set( KSCPLockCodeDefaultInputMode , def_mode );
+ delete repository;
+ }
+
+ /* Set the value in the cenrep that the default lock code has been changed if it is not
+ * already set
+ * */
+ TRAP(err, repository = CRepository :: NewL(KCRUidSCPLockCode));
+
+ if(err == KErrNone) {
+ err = repository->Set(KSCPLockCodeDefaultLockCode, 0);
+ delete repository;
+ }
+ }
+ }
+ else
+ {
+ Dprint( (_L("CSCPServer::StoreEnhCode(): ERROR:\
+ failed to change ISA code, aborting storage operation: %d"), err ));
+
+ }
+
+ return err;
+ }
+
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS
+
+
+
+
+// ---------------------------------------------------------
+// TBool CSCPServer::IsOperationInProgress( TSCPAdminCommand aCommand )
+// Loops through the sessions on the server and and calls the
+// query command to check if the given operation is in progress.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TBool CSCPServer::IsOperationInProgress( TSCPAdminCommand aCommand )
+ {
+ Dprint( (_L("--> CSCPServer::IsOperationInProgress()") ));
+
+ // Iterate through the sessions and find out if one has started the given operation
+ TBool ret = EFalse;
+
+ iSessionIter.SetToFirst();
+ CSCPSession* curSession = NULL;
+ while ( ( curSession = static_cast<CSCPSession*>( iSessionIter++ ) ) != NULL )
+ {
+ if ( curSession->IsOperationInProgress( aCommand ) )
+ {
+ ret = ETrue;
+ break;
+ }
+ }
+
+ Dprint( (_L("<-- CSCPServer::IsOperationInProgress(): %d"), ret ));
+ return ret;
+ }
+
+
+
+
+// ---------------------------------------------------------
+// TBool CSCPServer::AcknowledgementReceived( TSCPAdminCommand aCommand )
+// Loops through the sessions on the server, sends the acknowledgements,
+// and checks if one was waiting for it (ETrue).
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TBool CSCPServer::AcknowledgementReceived( TSCPAdminCommand aCommand )
+ {
+ Dprint( (_L("--> CSCPServer::AcknowledgementReceived()") ));
+
+ // Iterate through the sessions and propagate the acknowledgement.
+ // Set the return parameter, if one was waiting for the ack
+ TBool ret = EFalse;
+
+ iSessionIter.SetToFirst();
+ CSCPSession* curSession = NULL;
+ while ( ( curSession = static_cast<CSCPSession*>( iSessionIter++ ) ) != NULL )
+ {
+ if ( curSession->AcknowledgeOperation( aCommand ) ) ret = ETrue;
+ }
+
+ Dprint( (_L("<-- CSCPServer::AcknowledgementReceived(): %d"), ret ));
+ return ret;
+ }
+
+
+
+
+// ---------------------------------------------------------
+// TInt CSCPServer::SetAutolockPeriod()
+// Sets the autolock period in either SharedData or CenRep.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TInt CSCPServer :: SetAutolockPeriodL(TInt aValue) {
+ Dprint( (_L("CSCPServer::SetAutolockPeriodL(): Setting the value") ));
+
+ TInt ret = KErrNone;
+
+
+ // Change the value in CenRep
+ ret = iALPeriodRep->Set( KSettingsAutoLockTime, aValue );
+
+ Dprint( (_L("[CSCPServer]-> SetAutolockPeriodL() <<<") ));
+ return ret;
+ }
+
+// ---------------------------------------------------------
+// TInt CSCPServer::GetAutolockPeriodL( TInt& aValue )
+// Gets the autolock period from either SharedData or CenRep.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TInt CSCPServer::GetAutolockPeriodL( TInt& aValue )
+ {
+ TInt ret = KErrNone;
+
+ Dprint( (_L("CSCPServer::GetAutolockPeriodL(): Getting the value") ));
+
+ // Fetch the value from CenRep
+ ret = iALPeriodRep->Get( KSettingsAutoLockTime, aValue );
+
+ return ret;
+ }
+
+
+
+
+// ---------------------------------------------------------
+// CSCPServer::ChangeCodePolicy()
+// Sets the new policy either internally or through the policy
+// engine.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TInt CSCPServer::ChangeCodePolicy( const TDesC& aValue )
+ {
+ TInt ret = KErrNone;
+
+ TLex lex( aValue );
+ TInt value;
+
+ ret = lex.Val( value );
+
+ if ( ret == KErrNone )
+ {
+ if ( ( value < 0 ) || ( value > 1 ) )
+ {
+ ret = KErrArgument;
+ }
+ else
+ {
+ Dprint( (_L("CSCPServer::ChangeCodePolicy(): %d"), value ));
+
+#ifdef SCP_USE_POLICY_ENGINE
+
+ RPolicyEngine policyEngine;
+ ret = policyEngine.Connect();
+
+ RPolicyManagement policyManagement;
+ if ( ret == KErrNone )
+ {
+ ret = policyManagement.Open( policyEngine );
+ }
+
+ TParserResponse response;
+
+ if ( ret == KErrNone )
+ {
+ Dprint( (_L("CSCPServer::ChangeCodePolicy(): Executing operation") ));
+ if ( value == 1 )
+ {
+ // Allow change
+ ret = policyManagement.ExecuteOperation(
+ KSCPCodePolicyAllowOperation,
+ response
+ );
+ }
+ else
+ {
+ // Deny change
+ ret = policyManagement.ExecuteOperation(
+ KSCPCodePolicyDisallowOperation,
+ response
+ );
+ }
+
+ if ( ret == KErrNone )
+ {
+ const TDesC8& retMsg = response.GetReturnMessage();
+
+ if ( retMsg.Compare( KSCPOKResponse ) != 0 )
+ {
+ #ifdef _DEBUG
+ TBuf<256> dummyBuf;
+ dummyBuf.Copy( retMsg );
+ Dprint( (_L("CSCPServer::ChangeCodePolicy(): Response not OK:\
+ %S"), &dummyBuf ));
+ #endif
+
+ // We must check this for an error as well
+ ret = KErrGeneral;
+ }
+ }
+ }
+
+ if ( policyManagement.SubSessionHandle() )
+ {
+ policyManagement.Close();
+ }
+
+ if ( policyEngine.Handle() )
+ {
+ policyEngine.Close();
+ }
+
+#else // !SCP_USE_POLICY_ENGINE
+
+ iCodePolicy = value;
+
+#endif // SCP_USE_POLICY_ENGINE
+ }
+ }
+
+ Dprint( (_L("<-- CSCPServer::ChangeCodePolicy(): %d"), ret ));
+ return ret;
+ }
+
+
+
+
+// ---------------------------------------------------------
+// CSCPServer:GetCodePolicy()
+// Gets the policy from internal storage of from the policy
+// engine.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TInt CSCPServer::GetCodePolicy( TDes& aValue )
+ {
+ Dprint( (_L("--> CSCPServer::GetCodePolicy()") ));
+ TInt ret = KErrNone;
+
+ aValue.Zero();
+
+#ifdef SCP_USE_POLICY_ENGINE
+ TResponse response;
+ RPolicyEngine policyEngine;
+ ret = policyEngine.Connect();
+
+ RPolicyRequest policyRequest;
+ if ( ret == KErrNone )
+ {
+ ret = policyRequest.Open( policyEngine );
+ }
+
+ if(ret == KErrNone) {
+ TRequestContext context;
+
+ using namespace PolicyEngineXACML;
+ TRAPD( err ,
+ context.AddResourceAttributeL( KResourceId,
+ KDeviceLockPasscodeVisibility,
+ KStringDataType)
+ );
+ if ( err == KErrNone )
+ {
+ ret = policyRequest.MakeRequest( context, response );
+ }
+ else
+ {
+ ret = err;
+ }
+ }
+
+ if ( ret == KErrNone )
+ {
+ if ( response.GetResponseValue() == EResponsePermit )
+ {
+ // Allow security code change
+ aValue.AppendNum( 1 );
+ }
+ else
+ {
+ // Do not allow security code change
+ aValue.AppendNum( 0 );
+ }
+ }
+
+ if ( policyRequest.SubSessionHandle() )
+ {
+ policyRequest.Close();
+ }
+
+ if ( policyEngine.Handle() )
+ {
+ policyEngine.Close();
+ }
+
+#else // !SCP_USE_POLICY_ENGINE
+
+ aValue.AppendNum( iCodePolicy );
+
+#endif // SCP_USE_POLICY_ENGINE
+
+ Dprint((_L("[CSCPServer] <<< GetCodePolicy(): %d"), ret));
+ return ret;
+ }
+
+
+
+
+// ---------------------------------------------------------
+// TInt CSCPServer::SetParameterValueL( TSCPParameterID aID, TDesC& aValue )
+// Handles the setting of the parameter values.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TInt CSCPServer::SetParameterValueL( TInt aID, const TDesC& aValue, TUint32 aCallerIdentity )
+ {
+ Dprint( (_L("--> CSCPServer::SetParameterValueL( %d )"), aID ));
+
+#ifdef __SCP_DEBUG
+ // Used to "emulate 3-button boot" in debug builds
+ if ( aID == 9999 )
+ {
+ iConfiguration.iConfigFlag = KSCPConfigUnknown;
+ iConfiguration.iSecCode = KSCPDefaultSecCode;
+ return KErrNone;
+ }
+#endif // __SCP_DEBUG
+
+ TInt lRetStatus(KErrNone);
+ Dprint(_L("[CSCPServer]-> Initiating branching on parameter..."));
+
+ switch ( aID )
+ {
+ case ( ESCPAutolockPeriod ):
+ // Flow through
+ case ( ESCPMaxAutolockPeriod ):
+ {
+ // Convert the value, and set it
+ TInt value;
+ TLex lex(aValue);
+ lRetStatus = lex.Val(value);
+
+
+ if((lRetStatus != KErrNone ) || ( value < 0) || ( value > KSCPAutolockPeriodMaximum )) {
+ lRetStatus = KErrArgument;
+ break;
+ }
+
+ //Check if the device memory is encrypted or not.
+ TBool encryptionEnabled = IsDeviceMemoryEncrypted();
+
+ // Value OK
+ if(aID == ESCPMaxAutolockPeriod)
+ {
+ if ( encryptionEnabled )
+ {
+ Dprint(_L("Memory is encrypted"));
+ if (( 0 == value) || value > KMaxAutolockPeriod)
+ {
+ Dprint((_L("Denying setting of max auto lock as value is %d"), value));
+ User::Leave( KErrPermissionDenied );
+ }
+
+ }
+ else
+ {
+ Dprint(_L("Memory is decrypted, hence no restrictions to max autolock"));
+ }
+
+ Dprint(_L("[CSCPServer]-> Branched to ESCPMaxAutolockPeriod..."));
+ CSCPParamDBController* lParamDB = CSCPParamDBController :: NewLC();
+ lRetStatus = SetBestPolicyL(RTerminalControl3rdPartySession :: EMaxTimeout, aValue, aCallerIdentity, lParamDB);
+
+ if(lRetStatus == KErrNone)
+ {
+ // Do we have to change the Autolock period as well?
+ TInt currentALperiod;
+ lRetStatus = GetAutolockPeriodL(currentALperiod);
+
+ if(lRetStatus == KErrNone)
+ {
+ if((iConfiguration.iMaxTimeout > 0) && ((iConfiguration.iMaxTimeout < currentALperiod) || (currentALperiod == 0)))
+ {
+ Dprint((_L("[CSCPServer]-> Changing AL period to Max. AL period (Current ALP: %d, Max. ALP: %d)"), currentALperiod, value));
+ lRetStatus = SetAutolockPeriodL(value);
+ }
+ }
+ else
+ {
+ Dprint((_L("[CSCPServer]-> ERROR: Couldn't get the Autolock period: %d"), lRetStatus));
+ }
+ }
+
+ CleanupStack :: PopAndDestroy(); //lParamDB
+ }
+
+ else
+ { // Autolock Period
+
+ //Code is commented as it is already taken care by the below condition #1343 irrespective of the drive encryption state.
+ /* if ( 0 == value )
+ {
+ if ( encryptionEnabled )
+ {
+ Dprint(_L("Permission denied!"));
+ User::Leave( KErrPermissionDenied );
+ }
+ }*/
+
+ Dprint(_L("[CSCPServer]-> Branched to ESCPAutolockPeriod..."));
+ // Check if this value is not allowed by the Max. Autolock period
+ if ((iConfiguration.iMaxTimeout > 0) && ((iConfiguration.iMaxTimeout < value) || (value == 0))) {
+ Dprint((_L("[CSCPServer]-> ERROR: The value %d for AL period not allowed (Max. AL period: %d)"), value, iConfiguration.iMaxTimeout));
+
+ lRetStatus = KErrArgument;
+ }
+ else {
+ lRetStatus = SetAutolockPeriodL(value);
+
+ if(lRetStatus != KErrNone) {
+ Dprint((_L("[CSCPServer]-> ERROR: Couldn't set the Autolock period: %d"), lRetStatus));
+ }
+ }
+ }
+ }
+ break;
+ case ESCPCodeChangePolicy:
+ Dprint(_L("[CSCPServer]-> Branched to ESCPCodeChangePolicy..."));
+ lRetStatus = ChangeCodePolicy( aValue );
+ break;
+ default: {
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS
+ Dprint(_L("[CSCPServer]-> Branched to default condition, aID=%d"), aID);
+
+ if(FeatureManager :: FeatureSupported(KFeatureIdSapDeviceLockEnhancements)) {
+ RPointerArray<HBufC> lSpecStrArray;
+ CleanupClosePushL(lSpecStrArray);
+
+ Dprint(_L("[CSCPServer]-> Creating an instance of the private DB..."));
+ CSCPParamDBController* lParamDB = CSCPParamDBController :: NewLC();
+ Dprint(_L("[CSCPServer]-> Private DB instance created successfully..."));
+
+ Dprint(_L("[CSCPServer]-> Creating ParamObject..."));
+ CSCPParamObject* lInParams = CSCPParamObject :: NewLC();
+ Dprint(_L("[CSCPServer]-> ParamObject created successfully..."));
+
+ //lInParams->Set(KSCPParamIdentity, aCallerIdentity);
+
+ /*
+ * Map KSCPParamIdentity with the SID of TCServer (not aCallerIdentity)
+ */
+ lInParams->Set(KSCPParamIdentity, this->Message().SecureId());
+
+ switch(aID) {
+ case RTerminalControl3rdPartySession :: EPasscodeAllowSpecific:
+ case RTerminalControl3rdPartySession :: EPasscodeClearSpecificStrings: {
+ RPointerArray<HBufC> lSharedStrArray;
+ CleanupClosePushL(lSharedStrArray);
+
+ /* If the choice is EPasscodeAllowSpecific then parse the specific strings mentioned and
+ * list the specific strings in an Array (multiple specific strings can be seperated with a single space)
+ * The Memory alloted for each of the tokens representing each individual specific string will be
+ * deallocated when the array lSpecStrArray is cleared by a call to ResetAndDestroy().
+ */
+ if(aID == RTerminalControl3rdPartySession :: EPasscodeAllowSpecific) {
+ TLex16 lex (aValue);
+ lex.Mark();
+
+ while(!lex.Eos()) {
+ while(lex.Peek() != ' ' && !lex.Eos()) {
+ lex.Inc();
+ }
+
+ const TDesC& lToken = lex.MarkedToken();
+ HBufC* lBuff(NULL);
+ TRAP(lRetStatus, lBuff = HBufC :: NewL(lToken.Length()));
+
+ if(lRetStatus != KErrNone) {
+ lSpecStrArray.ResetAndDestroy();
+ User :: Leave(lRetStatus);
+ }
+
+ lBuff->Des().Append(lToken);
+ lSpecStrArray.Append(lBuff);
+ lex.Inc();
+ lex.Mark();
+ }
+ }
+ else {
+ lRetStatus = lParamDB->GetValuesL(RTerminalControl3rdPartySession :: EPasscodeDisallowSpecific,
+ lSpecStrArray, aCallerIdentity);
+ }
+
+ TInt lCnt = lSpecStrArray.Count();
+ lInParams->Set(KSCPParamID, RTerminalControl3rdPartySession :: EPasscodeAllowSpecific);
+
+ for(TInt i=0; i < lCnt; i++) {
+ HBufC* lPtr = lSpecStrArray[i];
+ TBool lIsShared(EFalse);
+
+ TRAPD(lErr, lIsShared = lParamDB->IsParamValueSharedL(lSpecStrArray[i], aCallerIdentity));
+
+ if(lErr != KErrNone) {
+ lSpecStrArray.ResetAndDestroy();
+ lSharedStrArray.ResetAndDestroy();
+ User :: Leave(lErr);
+ }
+
+ if(EFalse == lIsShared) {
+ TUint16* ptr = const_cast<TUint16*>(lPtr->Des().Ptr());
+ TPtr valBuf(ptr, lPtr->Des().Length(), lPtr->Des().Length());
+ lInParams->Set(KSCPParamValue, valBuf);
+
+ CSCPParamObject* reply = iPluginManager->PostEvent(KSCPEventConfigurationQuery, *lInParams);
+
+ if((reply != NULL) && (reply->Get(KSCPParamStatus, lRetStatus) == KErrNone)) {
+ if(lRetStatus != KErrNone) {
+ lSpecStrArray.ResetAndDestroy();
+ lSharedStrArray.ResetAndDestroy();
+ User :: Leave(lRetStatus);
+ }
+
+ delete reply;
+ }
+ }
+ else {
+ lSpecStrArray.Remove(i);
+ lSharedStrArray.Append(lPtr);
+ i--;
+ lCnt--;
+ }
+ }
+
+ /*
+ * Drop all the 'disallow strings' that are not shared between any other applications from the database.
+ */
+ TRAPD(lErr, lRetStatus = lParamDB->DropValuesL(RTerminalControl3rdPartySession :: EPasscodeDisallowSpecific, lSpecStrArray));
+
+ if(lErr != KErrNone) {
+ lSpecStrArray.ResetAndDestroy();
+ lSharedStrArray.ResetAndDestroy();
+ User :: Leave(lErr);
+ }
+
+ if(lRetStatus == KErrNone) {
+ /*
+ * Drop the entries of 'disallow strings' of only the called application
+ * (Any application that shares these 'disallow strings' will not be affected)
+ */
+ TRAP(lErr, lRetStatus = lParamDB->DropValuesL(RTerminalControl3rdPartySession :: EPasscodeDisallowSpecific,
+ lSharedStrArray, aCallerIdentity));
+
+ if(lErr != KErrNone) {
+ lSpecStrArray.ResetAndDestroy();
+ lSharedStrArray.ResetAndDestroy();
+ User :: Leave(lErr);
+ }
+
+ if(lRetStatus != KErrNone) {
+ Dprint(_L("[CSCPServer]-> Unable to drop 'disallow strings' from the private database..."));
+ }
+ }
+ else {
+ Dprint(_L("[CSCPServer]-> Unable to drop unshared 'disallow strings' from the private database..."));
+ }
+
+ lSharedStrArray.ResetAndDestroy();
+ CleanupStack :: PopAndDestroy(); // lSharedStrArray
+ }
+ break;
+ default: {
+ lInParams->Set(KSCPParamID, aID);
+ TUint16* ptr = const_cast<TUint16*>(aValue.Ptr());
+ TPtr valBuf(ptr, aValue.Length(), aValue.Length());
+ lInParams->Set(KSCPParamValue, valBuf);
+
+ Dprint(_L("[CSCPServer]-> INFO: Posting the event to the plugins..."));
+ CSCPParamObject* reply = iPluginManager->PostEvent(KSCPEventConfigurationQuery, *lInParams);
+
+ if((reply != NULL) && (reply->Get(KSCPParamStatus, lRetStatus) == KErrNone)) {
+ if(lRetStatus == KErrNone) {
+ Dprint(_L("[CSCPServer]-> INFO: The event was consumed by one of the plugins, initiating storage activities (if any)..."));
+ // Check if the plugin wishes to save the parameters itself
+ TInt storage = KSCPStorageCommon;
+ reply->Get(KSCPParamStorage, storage);
+
+ if(storage == KSCPStoragePrivate) {
+ switch(aID) {
+ /* The plugin will take care of storing the values for EPasscodeDisallowSpecific, this is to make sure the
+ * value is updated accordingly even in the private database (which is used as a reference to set the best policy-done
+ * as per MfE-Part 3 requirement
+ */
+ case RTerminalControl3rdPartySession :: EPasscodeDisallowSpecific: {
+ TLex16 lex (aValue);
+ lex.Mark();
+
+ while(!lex.Eos()) {
+ while(lex.Peek() != ' ' && !lex.Eos()) {
+ lex.Inc();
+ }
+
+ const TDesC& lToken = lex.MarkedToken();
+ HBufC* lBuff(NULL);
+ TInt lErr(KErrNone);
+ TRAP(lErr, lBuff = HBufC :: NewL(lToken.Length()));
+
+ if(lErr != KErrNone) {
+ lSpecStrArray.ResetAndDestroy();
+ delete reply;
+ User :: Leave(lErr);
+ }
+
+ lBuff->Des().Append(lToken);
+ lSpecStrArray.Append(lBuff);
+ lex.Inc();
+ lex.Mark();
+ }
+
+ TInt lRet(KErrNone);
+
+ TRAP(lRet, lRetStatus = lParamDB->SetValuesL(RTerminalControl3rdPartySession :: EPasscodeDisallowSpecific,
+ lSpecStrArray, aCallerIdentity));
+
+ if(lRet != KErrNone) {
+ lRetStatus = lRet;
+ }
+ }
+ break;
+ default:
+ // Don't store the parameter, the plugin will handle this
+ Dprint((_L("[CSCPServer]-> Param %d stored in private storage..."), aID));
+ break;
+ }
+ }
+ else {
+ Dprint((_L("[CSCPServer]-> Param %d stored in common storage..."), aID));
+ lRetStatus = SetBestPolicyL(aID, aValue, aCallerIdentity, lParamDB);
+ }
+ }
+ }
+ else {
+ Dprint(_L("[CSCPServer]-> INFO: Event posting failed, reply=%d"), reply);
+ }
+
+ delete reply;
+ break;
+ }
+ }
+
+ lSpecStrArray.ResetAndDestroy();
+ CleanupStack :: PopAndDestroy(3); // lSpecStrArray, lParamDB, lInParams
+ }
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS
+ break;
+ }
+ }
+
+ Dprint((_L("[CSCPServer]-> <<< SetParameterValueL(): %d"), lRetStatus));
+ return lRetStatus;
+}
+// ---------------------------------------------------------
+// TInt CSCPServer::GetParameterValueL( TSCPParameterID aID, TDes& aValue )
+// Handles the fetching of parameter values.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TInt CSCPServer::GetParameterValueL( TInt aID, TDes& aValue, TUint32 aCallerIdentity )
+ {
+ Dprint( (_L("CSCPServer::GetParameterValueL( %d )"), aID ));
+ TInt ret = KErrNone;
+
+ switch ( aID )
+ {
+ case ( ESCPAutolockPeriod ):
+ {
+ // Get the actual autolock period
+ TInt value;
+ if ( GetAutolockPeriodL( value ) != KErrNone )
+ {
+ Dprint( (_L("CSCPServer::SetParameterValueL(): ERROR: Couldn't \
+ get the Autolock period") ));
+ }
+ else
+ {
+ aValue.Zero();
+ aValue.AppendNum(value);
+ }
+ }
+ break;
+
+ case ( ESCPMaxAutolockPeriod ):
+ {
+ // Just fetch the value into the buffer
+ aValue.Zero();
+ aValue.AppendNum( iConfiguration.iMaxTimeout );
+ }
+ break;
+
+ case ( ESCPCodeChangePolicy ):
+ {
+ ret = GetCodePolicy( aValue );
+ }
+ break;
+
+ default:
+ ret = KErrNotSupported;
+
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS
+if(FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+ {
+
+ // "Ask" the plugins, if this caller is allowed to access this value or
+ // if the value is in private storage, retrieve the value.
+ CSCPParamObject* inParams = CSCPParamObject::NewL();
+ CleanupStack::PushL( inParams );
+ inParams->Set( KSCPParamID, aID );
+ inParams->Set( KSCPParamIdentity, aCallerIdentity );
+
+ CSCPParamObject* repParams =
+ iPluginManager->PostEvent( KSCPEventRetrieveConfiguration, *inParams );
+
+ CleanupStack::PopAndDestroy( inParams );
+
+ TBool getFromCommonStorage = ETrue;
+ TInt status;
+ if ( ( repParams != NULL ) &&
+ ( repParams->Get( KSCPParamStatus, status ) == KErrNone ) )
+ {
+ ret = status;
+ if ( ret != KErrNone )
+ {
+ getFromCommonStorage = EFalse;
+ Dprint( (_L("CSCPServer::GetParameterValueL():\
+ Retrieve configuration for param %d not OK: %d"), aID, ret ));
+ }
+ else
+ {
+ // Has the plugin sent the value?
+ TInt valueLen = repParams->GetParamLength( KSCPParamValue );
+ if ( valueLen > 0 )
+ {
+ getFromCommonStorage = EFalse;
+ // Try to retrieve the value (Get will check for overflow)
+ ret = repParams->Get( KSCPParamValue, aValue );
+ }
+ }
+ }
+
+ if ( getFromCommonStorage )
+ {
+ // OK, no objection, so try to get the value from common storage
+ ret = iPluginEventHandler->GetParameters().Get( aID, aValue );
+ }
+
+ if ( repParams != NULL )
+ {
+ delete repParams;
+ }
+ }
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS
+
+ break;
+ }
+
+ Dprint( (_L("<-- CSCPServer::GetParameterValueL(): %d"), ret ));
+ return ret;
+ }
+
+
+
+
+// ---------------------------------------------------------
+// static TBool CSCPServer::IsValidISACode( TDes& aCode )
+// Checks that the given string is a valid ISA security code.
+// That is, exacly 5 chars, and contains only digits.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+
+TBool CSCPServer::IsValidISACode( TDes& aCode )
+ {
+ TBool ret = ETrue;
+
+ if ( aCode.Length() != KSCPCodeMaxLen )
+ {
+ ret = EFalse;
+ }
+ else
+ {
+ for ( TInt i = 0; i < aCode.Length(); i++ )
+ {
+ if ( !( ((TChar)aCode[i]).IsDigit() ) )
+ {
+ ret = EFalse;
+ }
+ }
+ }
+
+ return ret;
+ }
+
+
+
+
+// ---------------------------------------------------------
+// void CSCPServer::SessionClosed()
+// Checks if this was the final session. If so, exit the
+// server thread.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+
+void CSCPServer::SessionClosed()
+ {
+ iSessionIter.SetToFirst();
+ iSessionIter++; // Skip the closing session
+
+ if ( iSessionIter++ == NULL )
+ {
+ // No more sessions
+ Dprint( (_L("CSCPServer::SessionClosed(): No more sessions, starting timeout") ));
+
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS
+if(FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+ {
+ // Save the plugin configuration
+ TRAP_IGNORE( iPluginEventHandler->WritePluginConfigurationL() );
+ }
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS
+
+ // Start shutdown timer
+ TRAPD( err, iShutdownTimer = CSCPTimer::NewL( KSCPServerShutdownTimeout,
+ NULL,
+ this ) );
+ if ( err != KErrNone )
+ {
+ // Cannot create the timer!
+ // No more sessions
+ Dprint( (_L("CSCPServer::SessionClosed(): ERROR: Timer creation failed! Exiting..")));
+ iShutdownTimer = NULL;
+ Timeout( NULL );
+ }
+ }
+ }
+
+
+
+// ---------------------------------------------------------
+// void CSCPServer::SessionOpened()
+// Stops the shutdown timer, if started.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+void CSCPServer::SessionOpened()
+ {
+ // Stop the shutdown timer
+ if ( iShutdownTimer != NULL )
+ {
+ delete iShutdownTimer;
+ iShutdownTimer = NULL;
+ }
+ }
+
+
+
+
+// ---------------------------------------------------------
+// void CSCPServer::Timeout()
+// Shuts down the server stopping the active scheduler since
+// the shutdown timer has elapsed.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+void CSCPServer::Timeout( TAny* aParam )
+ {
+ (void)aParam;
+
+ delete iShutdownTimer;
+ iShutdownTimer = NULL;
+
+ Dprint( (_L("CSCPServer::Timeout(): Shutting down SCP server") ));
+
+ CActiveScheduler::Stop();
+ }
+
+
+
+// ********************** NEW FEATURES ********************>>>>
+
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS
+
+// ---------------------------------------------------------
+// CSCPServer::IsValidEnhCode()
+// Checks that the given buffer is an alphanumeric string
+// and its length is between the minimum and maximum.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TBool CSCPServer::IsValidEnhCode( TDes& aCode )
+ {
+
+ if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+ {
+ return KErrNotSupported;
+ }
+ TBool ret = ETrue;
+
+ // Check length
+ if ( ( aCode.Length() < KSCPPasscodeMinLength ) ||
+ ( aCode.Length() > KSCPPasscodeMaxLength ) )
+ {
+ ret = EFalse;
+ }
+
+ // Check the characters
+ if ( ret )
+ {
+ for ( TInt i = 0; i < aCode.Length(); i++ )
+ {
+ TChar curChar = aCode[i];
+ TChar::TCategory chCat = curChar.GetCategory();
+ if ( curChar < 1 || curChar > 126 || curChar.IsSpace() )
+ /* if ( ( !curChar.IsAlphaDigit() ) && ( chCat != TChar::ENdCategory ) ) */
+ {
+ ret = EFalse;
+ }
+ }
+ }
+
+ return ret;
+ }
+
+
+// ---------------------------------------------------------
+// CSCPServer::IsCodeBlocked()
+// Checks if the code is blocked, and zeroes the attempt counter
+// when necessary.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TBool CSCPServer::IsCodeBlocked()
+ {
+
+ if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+ {
+ return KErrNotSupported;
+ }
+ TBool ret = EFalse;
+
+ if ( iConfiguration.iBlockedAtTime.Compare( KSCPNotBlocked ) == 0 )
+ {
+ ret = EFalse;
+ }
+ else
+ {
+ TTime curTime;
+ curTime.UniversalTime();
+
+ TTimeIntervalMinutes interval = KSCPCodeBlockedTimeMin;
+
+ TInt64 savedTime;
+ TLex lex( iConfiguration.iBlockedAtTime );
+ ret = lex.Val( savedTime );
+
+ if ( ret == KErrNone )
+ {
+ TTime configTime( savedTime );
+ if ( ( configTime + interval ) > curTime )
+ {
+ Dprint( (_L("CSCPServer::IsCodeBlocked(): Code BLOCKED") ));
+ // Restart the timer
+ iConfiguration.iBlockedAtTime.Zero();
+ iConfiguration.iBlockedAtTime.AppendNum( curTime.Int64() );
+
+ ret = ETrue;
+ }
+ else
+ {
+ // Not blocked anymore
+
+ Dprint( (_L("CSCPServer::IsCodeBlocked(): Resetting code block") ));
+ iConfiguration.iFailedAttempts = 0;
+ iConfiguration.iBlockedAtTime.Zero();
+ iConfiguration.iBlockedAtTime.Copy( KSCPNotBlocked );
+
+ ret = EFalse;
+ }
+
+ TRAPD( err, iConfiguration.WriteSetupL() );
+ if ( err != KErrNone )
+ {
+ Dprint( (_L("CSCPServer::IsCodeBlocked(): WARNING:\
+ failed to write configuration: %d"), err ));
+
+ }
+ }
+ }
+
+ return ret;
+ }
+
+
+
+
+// ---------------------------------------------------------
+// CSCPServer::SendInvalidDOSCode()
+// Resets the DOS password attempts if required and verifies the
+// code.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+void CSCPServer::SendInvalidDOSCode( RMobilePhone::TMobilePassword& aCodeToSend )
+ {
+
+ if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+ {
+ return ;
+ }
+ // Reset the DOS-side PSW-attempts by changing the code to the same one
+ RMobilePhone::TMobilePassword correctPsw;
+ TRAPD( err,
+ GetCode( correctPsw );
+ ChangeISACodeL( correctPsw );
+ );
+ if ( err != KErrNone )
+ {
+ Dprint( (_L("CSCPServer::SendInvalidDOSCode(): WARNING:\
+ DOS code change failed, where it shouldn't have: %d"), err ));
+ }
+
+ // Send the incorrect code to DOS side
+ TRAPD( ret, CheckISACodeL( aCodeToSend ) );
+ #ifndef __WINS__
+ if ( ( ret != KErrAccessDenied ) && ( ret != KErrGsm0707IncorrectPassword ) )
+ {
+ Dprint( (_L("CSCPServer::SendInvalidDOSCode(): WARNING:\
+ invalid DOS code validation error: %d"), ret ));
+ }
+ #endif // __WINS__
+ }
+
+
+
+
+// ---------------------------------------------------------
+// CSCPServer::IsCorrectEnhCode()
+// Checks if the given code is the correct enhanced code.
+// If the configuration is not up-to-date, the code will be hashed
+// and verified from the ISA-side.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TInt CSCPServer::IsCorrectEnhCode( TDes& aCode, TInt aFlags )
+ {
+
+ if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+ {
+ return KErrNotSupported;
+ }
+ TInt ret = KErrAccessDenied;
+
+ // Hash the code
+ TBuf<KSCPMaxHashLength> hashBuf;
+ hashBuf.Zero();
+ iPluginEventHandler->HashInput( aCode, hashBuf );
+
+ TInt ISACode = HashISACode( hashBuf );
+
+ RMobilePhone::TMobilePassword pswCandidate;
+ pswCandidate.Zero();
+ pswCandidate.AppendNum( ISACode );
+
+ TBool enhancedCodeMatches = EFalse;
+ if ( hashBuf.Compare( iConfiguration.iEnhSecCode ) == 0 )
+ {
+ enhancedCodeMatches = ETrue;
+ }
+
+ // Check if the code is blocked (don't check if we're out-of-sync)
+ if ( ( iConfiguration.iConfigFlag == KSCPConfigOK ) && ( IsCodeBlocked() ) )
+ {
+ if ( aFlags & KSCPEtelRequest )
+ {
+ // Check if the code is correct
+ if ( enhancedCodeMatches )
+ {
+ // Mess-up the code
+ RMobilePhone::TMobilePassword codeToSend;
+ codeToSend.Zero();
+ codeToSend.AppendNum( ISACode + 1 );
+
+ SendInvalidDOSCode( codeToSend );
+ }
+ else
+ {
+ // OK, the code is already invalid
+ SendInvalidDOSCode( pswCandidate );
+ }
+ }
+ return KErrLocked;
+ }
+
+ TBool writeSetup = EFalse;
+
+ if ( iConfiguration.iConfigFlag == KSCPConfigOK )
+ {
+ // Normal situation: we have the correct code stored.
+ // Compare the hashes (hashing error will result in EFalse )
+ if ( enhancedCodeMatches )
+ {
+ ret = KErrNone;
+
+ if ( aFlags & KSCPEtelRequest )
+ {
+ // Send the correct code to DOS side
+ TRAP( ret, CheckISACodeL( pswCandidate ) );
+ }
+
+ if ( ret == KErrNone )
+ {
+ if ( iConfiguration.iFailedAttempts > 0 )
+ {
+ iConfiguration.iFailedAttempts = 0;
+ Dprint( (_L("CSCPServer::IsCorrectEnhCode():KErrAccessDenied: iFailedAttempts (%d)."), iConfiguration.iFailedAttempts ));
+ writeSetup = ETrue;
+ }
+ }
+ else
+ {
+ Dprint( (_L("CSCPServer::IsCorrectEnhCode(): WARNING:\
+ ISA code validation failed, where it shouldn't have: %d"), ret ));
+ }
+ }
+ else
+ {
+ ret = KErrAccessDenied;
+
+ iConfiguration.iFailedAttempts++;
+ Dprint( (_L("CSCPServer::IsCorrectEnhCode():KErrAccessDenied: iFailedAttempts (%d)."), iConfiguration.iFailedAttempts ));
+ writeSetup = ETrue;
+
+ if ( iConfiguration.iFailedAttempts == KSCPCodeBlockLimit )
+ {
+ // Block the code
+ TTime curTime;
+ curTime.UniversalTime();
+
+ iConfiguration.iBlockedAtTime.Zero();
+ iConfiguration.iBlockedAtTime.AppendNum( curTime.Int64() );
+
+ // The code will be blocked for now on
+ ret = KSCPErrCodeBlockStarted;
+ }
+
+ if ( aFlags & KSCPEtelRequest )
+ {
+ SendInvalidDOSCode( pswCandidate );
+ }
+ }
+ }
+ else
+ {
+ // iConfiguration.iConfigFlag == KSCPConfigInvalid or KSCPConfigUnknown
+
+ // We might be out-of-sync, no idea about the real code.
+ // Check if the DOS code hashed from the given code is correct.
+ Dprint( (_L("CSCPServer::IsCorrectEnhCode(): Attempting to correct OoS situation.") ));
+
+ TRAP( ret, CheckISACodeL( pswCandidate ) );
+
+ if ( ret == KErrNone )
+ {
+ // OK, we must assume that this is the correct code, since
+ // the hashed DOS code is correct. Save the codes, and return OK.
+
+ Dprint( (_L("CSCPServer::IsCorrectEnhCode(): Given code has the correct hash (%d)\
+ , saving codes."), ISACode ));
+
+ iConfiguration.iEnhSecCode.Zero();
+ iConfiguration.iEnhSecCode.Copy( hashBuf );
+
+ iConfiguration.iSecCode.Zero();
+ iConfiguration.iSecCode.AppendNum( ISACode );
+
+ // Unset the invalid configuration flag
+ iConfiguration.iConfigFlag = KSCPConfigOK;
+ writeSetup = ETrue;
+ }
+ else
+ {
+
+ Dprint( (_L("CSCPServer::IsCorrectEnhCode(): Given code does not have the \
+ correct hash: ret; %d user enter password: %d"), ret ));
+ TRAP( ret, CheckISACodeL( aCode ) );
+ if (ret == KErrNone)
+ {
+ //store this code in our interal storage as it is used as oldpassword while changing at ISA side in next command
+ //ChangeISACodeL.
+ iConfiguration.iSecCode.Zero();
+ iConfiguration.iSecCode.Append( aCode );
+ TRAP(ret,ChangeISACodeL(pswCandidate));
+ }
+ if (ret == KErrNone)
+ {
+ iConfiguration.iEnhSecCode.Zero();
+ iConfiguration.iEnhSecCode.Copy( hashBuf );
+
+ iConfiguration.iSecCode.Zero();
+ iConfiguration.iSecCode.AppendNum( ISACode );
+
+ // Unset the invalid configuration flag
+ iConfiguration.iConfigFlag = KSCPConfigOK;
+ writeSetup = ETrue;
+ }
+ }
+ }
+
+ // Write setup if needed
+ if ( writeSetup )
+ {
+ TRAPD( err, iConfiguration.WriteSetupL() );
+ if ( err != KErrNone )
+ {
+ Dprint( (_L("CSCPServer::IsCorrectEnhCode(): WARNING:\
+ failed to write configuration: %d"), err ));
+ }
+ }
+
+ return ret;
+ }
+
+
+
+// ---------------------------------------------------------
+// CSCPServer::CheckCodeAndGiveISA()
+// Check the given code, and notify the plugins of the result.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TInt CSCPServer::CheckCodeAndGiveISAL( TDes& aCodeToCheck,
+ TDes& aISACodeToReturn,
+ CSCPParamObject*& aRetParams,
+ TInt aFlags )
+ {
+
+ if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+ {
+ return KErrNotSupported;
+ }
+ TInt ret = KErrNone;
+ TInt status = KErrNone;
+
+ // Check the code, note that IsCorrectEnhCode might change the stored code,
+ // so we'll get the code after the call.
+
+ TBool isSuccessful = EFalse;
+
+ status = IsCorrectEnhCode( aCodeToCheck, aFlags );
+
+ if ( status == KErrLocked )
+ {
+ // If the code is locked, no attempts count as failed or successful
+ return status;
+ }
+ else if ( status == KErrNone )
+ {
+ // OK, successful authentication
+ TSCPSecCode realCode;
+ ret = GetCode( realCode );
+
+ User::LeaveIfError( ret );
+
+ aISACodeToReturn.Copy( realCode );
+ isSuccessful = ETrue;
+ }
+ else // KSCPErrCodeBlockStarted or KErrAccessDenied
+ {
+ // Authentication attempt failed
+ TSCPSecCode realCode;
+ ret = GetCode( realCode );
+
+ User::LeaveIfError( ret );
+
+ TSCPSecCode fakeCode;
+ do
+ {
+ // Create a fake code, which is between 10000-99999
+ fakeCode.Zero();
+ TUint32 code = Math::Random();
+ code = code % 90000 + 10000;
+ fakeCode.AppendNum( code );
+ } while ( fakeCode.Compare( realCode ) == 0 );
+
+ aISACodeToReturn.Copy( fakeCode );
+
+ if ( status == KSCPErrCodeBlockStarted )
+ {
+ status = KErrLocked; // Set this as the external error code
+ }
+ }
+
+ // Send information about the authentication attempt to the plugins
+ CSCPParamObject* inParams = CSCPParamObject::NewL();
+ CleanupStack::PushL( inParams );
+ inParams->Set( KSCPParamContext, KSCPContextQueryPsw );
+
+ if ( isSuccessful )
+ {
+ // Authentication successful
+ inParams->Set( KSCPParamStatus, KErrNone );
+ }
+ else
+ {
+ // Authentication failed
+ inParams->Set( KSCPParamStatus, KErrAccessDenied );
+ }
+
+ CSCPParamObject* repParams =
+ iPluginManager->PostEvent( KSCPEventAuthenticationAttempted, *inParams );
+
+ CleanupStack::PopAndDestroy( inParams );
+
+ if ( repParams != NULL )
+ {
+ // No status information here, just propagate the paramobject
+ aRetParams = repParams; // pointer ownership changed
+ }
+
+ return status;
+ }
+
+
+
+
+// ---------------------------------------------------------
+// CSCPServer::CheckAndChangeEnhCodeL()
+// Check the given code, and if correct, send it to the plugins
+// for validation.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TInt CSCPServer::CheckAndChangeEnhCodeL( TDes& aOldPass,
+ TDes& aNewPass,
+ CSCPParamObject*& aRetParams,
+ TSCPSecCode& aNewDOSCode )
+ {
+
+ if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+ {
+ return KErrNotSupported;
+ }
+ TInt ret = KErrNone;
+
+ ret = IsCorrectEnhCode( aOldPass, 0 );
+ if ( ret == KErrNone )
+ {
+ // Authentication successful
+ CSCPParamObject* inParams = CSCPParamObject::NewL();
+ CleanupStack::PushL( inParams );
+
+ inParams->Set( KSCPParamStatus, KErrNone );
+ inParams->Set( KSCPParamContext, KSCPContextChangePsw );
+ CSCPParamObject* repParams =
+ iPluginManager->PostEvent( KSCPEventAuthenticationAttempted, *inParams );
+
+ if ( repParams != NULL )
+ {
+ // Ignore the return params at this point
+ delete repParams;
+ }
+
+ inParams->Reset();
+
+ // Validate the code
+ inParams->Set( KSCPParamPassword, aNewPass );
+
+ repParams = iPluginManager->PostEvent( KSCPEventValidate, *inParams );
+
+ CleanupStack::PopAndDestroy( inParams );
+
+ if ( repParams != NULL )
+ {
+ // Check if the validation failed
+ TInt status;
+ if ( repParams->Get( KSCPParamStatus, status ) == KErrNone )
+ {
+ if ( status != KErrNone )
+ {
+ ret = status;
+ }
+ }
+
+ aRetParams = repParams; // pointer ownership changed
+ }
+
+ // Set the new code, if it was OK
+ if ( ret == KErrNone )
+ {
+ if ( IsValidEnhCode( aNewPass ) )
+ {
+ ret = StoreEnhCode( aNewPass, &aNewDOSCode );
+ }
+ else
+ {
+ // Invalid code format! Should not happen at this point, but make sure.
+ ret = KErrArgument;
+ }
+
+ if ( ret == KErrNone )
+ {
+ CSCPParamObject* inParams = CSCPParamObject::NewL();
+ CleanupStack::PushL( inParams );
+ inParams->Set( KSCPParamPassword, aNewPass );
+
+ CSCPParamObject* repParams =
+ iPluginManager->PostEvent( KSCPEventPasswordChanged, *inParams );
+
+ CleanupStack::PopAndDestroy( inParams );
+
+ if ( repParams != NULL )
+ {
+ // Ignore the return params at this point
+ delete repParams;
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( ( ret == KErrAccessDenied ) || ( ret == KSCPErrCodeBlockStarted ) )
+ {
+ // Authentication failed
+ CSCPParamObject* inParams = CSCPParamObject::NewL();
+ CleanupStack::PushL( inParams );
+
+ inParams->Set( KSCPParamStatus, KErrAccessDenied );
+ inParams->Set( KSCPParamContext, KSCPContextChangePsw );
+ CSCPParamObject* repParams =
+ iPluginManager->PostEvent( KSCPEventAuthenticationAttempted, *inParams );
+
+ CleanupStack::PopAndDestroy( inParams );
+
+ if ( repParams != NULL )
+ {
+ // No status information here, just propagate the paramobject
+ aRetParams = repParams; // pointer ownership changed
+ }
+
+ if ( ret == KSCPErrCodeBlockStarted )
+ {
+ ret = KErrLocked; // Set this as the external error code
+ }
+ }
+ }
+
+ return ret;
+ }
+
+
+
+
+// ---------------------------------------------------------
+// CSCPServer::GetEventHandlerL()
+// Return a pointer to the event handler object.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+MSCPPluginEventHandler* CSCPServer::GetEventHandlerL()
+ {
+ if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+ {
+ return NULL;
+ }
+ return iPluginEventHandler;
+ }
+
+
+
+// ---------------------------------------------------------
+// CSCPServer::IsPasswordChangeAllowedL()
+// Check from the plugins if the password is allowed to be changed.
+//
+// Status : Approved
+// ---------------------------------------------------------
+
+TInt CSCPServer::IsPasswordChangeAllowedL( CSCPParamObject*& aRetParams )
+ {
+
+ if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+ {
+ return KErrNotSupported;
+ }
+ TInt ret = KErrNone;
+
+ // Post the event to the plugins to find out if the password can
+ // be changed
+
+ CSCPParamObject* inParams = CSCPParamObject::NewL();
+ CleanupStack::PushL( inParams );
+
+ // No additional parameters
+
+ CSCPParamObject* repParams =
+ iPluginManager->PostEvent( KSCPEventPasswordChangeQuery, *inParams );
+
+ CleanupStack::PopAndDestroy( inParams );
+
+ if ( repParams != NULL )
+ {
+ // Check status
+ TInt status;
+ if ( repParams->Get( KSCPParamStatus, status ) == KErrNone )
+ {
+ if ( status != KErrNone )
+ {
+ ret = status;
+ }
+ }
+
+ aRetParams = repParams; // pointer ownership changed
+ }
+
+ return ret;
+ }
+
+
+ // ---------------------------------------------------------
+// CSCPServer::IsDeviceMemoryEncrypted
+// Checks if phone memory is encrypted or not.
+// ---------------------------------------------------------
+TBool CSCPServer::IsDeviceMemoryEncrypted()
+ {
+ Dprint(_L("CSCPServer::IsDeviceMemoryEncrypted >>"));
+
+ TBool ret(EFalse);
+
+ //First check if the feature is supported on device
+ TRAPD(ferr, FeatureManager::InitializeLibL());
+ if (ferr != KErrNone)
+ {
+ Dprint(_L("feature mgr initialization error, %d"), ferr);
+ return EFalse;
+ }
+ ret = FeatureManager::FeatureSupported( KFeatureIdFfDeviceEncryptionFeature);
+ FeatureManager::UnInitializeLib();
+
+ //If feature is supported, check if any drive is encrypted.
+ if (ret)
+ {
+ CDevEncSession* devEncSession = new CDevEncSession( EDriveC );
+
+ if (!devEncSession)
+ {
+ Dprint(_L("Can't instantiate device encryption session.."));
+ return EFalse;
+ }
+
+ TInt err = devEncSession->Connect();
+ if (err == KErrNone)
+ {
+ //Session with device encryption is established. Check if any drive is encrypted
+ TInt encStatus (KErrNone);
+ TInt err = devEncSession->DiskStatus( encStatus );
+ Dprint(_L("err = %d, encstatus = %d"), err, encStatus);
+ if ( err == KErrNone && encStatus != EDecrypted )
+ {
+ Dprint(_L("Memory is encrypted"));
+ ret = ETrue;
+ }
+ else
+ {
+ Dprint(_L("Memory is not encrypted"));
+ ret = EFalse;
+ }
+ }
+ else
+ {
+ Dprint(_L("Error %d while establishing connection with device encryption engine"), err);
+ ret = EFalse;
+ }
+
+ delete devEncSession; devEncSession = NULL;
+ }
+
+ Dprint(_L("CSCPServer::IsDeviceMemoryEncrypted, ret = %d <<"), ret);
+ return ret;
+ }
+
+
+/**
+* Sets the best policy for the parameters that are under conflict. This is part of changes done for MFE-requirement part3.
+* @params aID: The ID of the parameter that needs to be set
+* aValue: Value of the parameter identified in aID
+* aCalledIdentity: The UID of the called application/process
+*
+* @return TInt: KErrNone is successful, otherwise a system error code
+*/
+TInt CSCPServer :: SetBestPolicyL( TInt aID, const TDesC& aValue, TUint32 aCallerIdentity, CSCPParamDBController* aParamDB ) {
+ Dprint( (_L("[CSCPServer]-> SetBestPolicyL() >>>")));
+ Dprint( (_L("[CSCPServer]-> ParamID=%d "), aID, aValue));
+ Dprint( (_L("[CSCPServer]-> ParamValue=%d "), aValue));
+
+ TBool lFirstTime(EFalse);
+ TInt32 lNumValue (-1);
+ TInt32 lNumValDB (-1);
+ TInt32 lRetStatus = KErrNone;
+
+ switch(aID) {
+ case RTerminalControl3rdPartySession :: EMaxTimeout:
+ case RTerminalControl3rdPartySession :: EPasscodeMinLength:
+ case RTerminalControl3rdPartySession :: EPasscodeMaxLength:
+ case RTerminalControl3rdPartySession :: EPasscodeRequireUpperAndLower:
+ case RTerminalControl3rdPartySession :: EPasscodeRequireCharsAndNumbers:
+ case RTerminalControl3rdPartySession :: EPasscodeExpiration:
+ case RTerminalControl3rdPartySession :: EPasscodeMaxRepeatedCharacters:
+ case RTerminalControl3rdPartySession :: EPasscodeMinChangeTolerance:
+ case RTerminalControl3rdPartySession :: EPasscodeMinChangeInterval:
+ case RTerminalControl3rdPartySession :: EPasscodeCheckSpecificStrings:
+ case RTerminalControl3rdPartySession :: EPasscodeMaxAttempts:
+ case RTerminalControl3rdPartySession :: EPasscodeConsecutiveNumbers:
+ case RTerminalControl3rdPartySession :: EPasscodeHistoryBuffer:
+ case RTerminalControl3rdPartySession :: EPasscodeMinSpecialCharacters:
+ case RTerminalControl3rdPartySession :: EPasscodeDisallowSimple:
+ break;
+ case RTerminalControl3rdPartySession :: EPasscodeClearSpecificStrings:
+ case RTerminalControl3rdPartySession :: EPasscodeDisallowSpecific:
+ case RTerminalControl3rdPartySession :: EPasscodeAllowSpecific:
+ return KErrNotSupported;
+ default:
+ // No best policy check required for parameters other than the above 19 (Only 19 of the current parameters conflict!)
+ TUint16* ptr = const_cast<TUint16*>( aValue.Ptr());
+ TPtr valBuf( ptr, aValue.Length(), aValue.Length());
+ lRetStatus = iPluginEventHandler->GetParameters().Set( aID, valBuf);
+ return lRetStatus;
+ }
+
+ TLex lex( aValue );
+ // Convert the parameter value to its numeric equivalent
+ if (lex.Val( lNumValue ) != KErrNone) {
+ return KErrArgument;
+ }
+
+ if(iOverrideForCleanup) {
+ Dprint( _L("[CSCPServer]-> SetBestPolicy() Overriding decision logic..."));
+ lRetStatus = aParamDB->DropValuesL(aID);
+ }
+ else {
+ // Fetch the previous value of the parameter from the private database
+ switch(aID) {
+ case RTerminalControl3rdPartySession :: EMaxTimeout:
+ case RTerminalControl3rdPartySession :: EPasscodeMinLength:
+ case RTerminalControl3rdPartySession :: EPasscodeMaxLength:
+ case RTerminalControl3rdPartySession :: EPasscodeRequireUpperAndLower:
+ case RTerminalControl3rdPartySession :: EPasscodeRequireCharsAndNumbers:
+ case RTerminalControl3rdPartySession :: EPasscodeExpiration:
+ case RTerminalControl3rdPartySession :: EPasscodeMaxRepeatedCharacters:
+ case RTerminalControl3rdPartySession :: EPasscodeMinChangeTolerance:
+ case RTerminalControl3rdPartySession :: EPasscodeMinChangeInterval:
+ case RTerminalControl3rdPartySession :: EPasscodeCheckSpecificStrings:
+ case RTerminalControl3rdPartySession :: EPasscodeMaxAttempts:
+ case RTerminalControl3rdPartySession :: EPasscodeConsecutiveNumbers:
+ case RTerminalControl3rdPartySession :: EPasscodeHistoryBuffer:
+ case RTerminalControl3rdPartySession :: EPasscodeMinSpecialCharacters:
+ case RTerminalControl3rdPartySession :: EPasscodeDisallowSimple: {
+ Dprint( (_L("[CSCPServer]-> Fetching the value of parameter '%d' from private database..."), aID));
+
+ TInt32 lAppID;
+
+ lRetStatus = aParamDB->GetValueL(aID, lNumValDB, lAppID);
+
+ switch(lRetStatus) {
+ case KErrNotFound: {
+ TInt lLSValue(0);
+ lFirstTime = ETrue;
+
+ switch(aID) {
+ case RTerminalControl3rdPartySession :: EMaxTimeout:
+ case RTerminalControl3rdPartySession :: EPasscodeMaxRepeatedCharacters:
+ case RTerminalControl3rdPartySession :: EPasscodeExpiration:
+ case RTerminalControl3rdPartySession :: EPasscodeMinChangeTolerance:
+ case RTerminalControl3rdPartySession :: EPasscodeMinChangeInterval:
+ case RTerminalControl3rdPartySession :: EPasscodeMaxAttempts:
+ case RTerminalControl3rdPartySession :: EPasscodeMaxLength:
+ case RTerminalControl3rdPartySession :: EPasscodeDisallowSimple:
+ /* For these parameters, if it is the first time that the values are being
+ set then no decision is imposed regarding the best policy...
+ */
+ break;
+ default:
+ // Get the default values for the parameter...
+ lRetStatus = iPluginEventHandler->GetParameters().Get(aID, lLSValue);
+ break;
+ }
+
+ lNumValDB = lLSValue;
+ Dprint((_L("[CSCPServer]-> Unable to fetch the value of parameter '%d' from private database, value from internal tree=%d"), aID, lLSValue));
+ }
+ break;
+ case KErrNone:
+ break;
+ default:
+ Dprint((_L("[CSCPServer]-> Failed to fetch parameter '%d' from the private database. ErrCode=%d"), aID, lRetStatus));
+ return lRetStatus;
+ }
+ break;
+ }
+ }
+
+ if(lNumValue == lNumValDB) {
+ Dprint(_L("[CSCPServer]-> INFO: New parameter value and value from the database are the same. Overriding SetBestPolicy()..."));
+ return KErrNone;
+ }
+
+ lRetStatus = KErrNone;
+
+ // Decision code that verifies if policy is strongest
+ switch(aID) {
+ case RTerminalControl3rdPartySession :: EMaxTimeout:
+ case RTerminalControl3rdPartySession :: EPasscodeMaxRepeatedCharacters:
+ case RTerminalControl3rdPartySession :: EPasscodeExpiration:
+ case RTerminalControl3rdPartySession :: EPasscodeMinChangeTolerance:
+ case RTerminalControl3rdPartySession :: EPasscodeMinChangeInterval:
+ case RTerminalControl3rdPartySession :: EPasscodeMaxAttempts:
+ if(!lFirstTime && ((lNumValue > lNumValDB) || (lNumValue == 0))) {
+ lRetStatus = KErrArgument;
+ }
+ break;
+ case RTerminalControl3rdPartySession :: EPasscodeMaxLength:
+ if(!lFirstTime && (lNumValue < lNumValDB)) {
+ lRetStatus = KErrArgument;
+ }
+ break;
+ case RTerminalControl3rdPartySession :: EPasscodeMinLength:
+ case RTerminalControl3rdPartySession :: EPasscodeHistoryBuffer:
+ case RTerminalControl3rdPartySession :: EPasscodeMinSpecialCharacters:
+ if(lNumValue < lNumValDB) {
+ lRetStatus = KErrArgument;
+ }
+ break;
+ case RTerminalControl3rdPartySession :: EPasscodeRequireUpperAndLower:
+ case RTerminalControl3rdPartySession :: EPasscodeRequireCharsAndNumbers:
+ case RTerminalControl3rdPartySession :: EPasscodeCheckSpecificStrings:
+ case RTerminalControl3rdPartySession :: EPasscodeConsecutiveNumbers:
+ case RTerminalControl3rdPartySession :: EPasscodeDisallowSimple:
+ if(lNumValue == false && lNumValDB == true) {
+ lRetStatus = KErrArgument;
+ }
+ break;
+ }
+
+ if(lRetStatus != KErrNone) {
+ return KErrArgument;
+ }
+
+ // Update the best policy to the DB as well as the local storage tree
+ Dprint((_L("[CSCPServer]-> Updating the value of parameter '%d' to private database...UID=%d"), aID, aCallerIdentity));
+
+ lRetStatus = aParamDB->SetValueL(aID, lNumValue, aCallerIdentity);
+ }
+
+ Dprint(_L("[CSCPServer]-> lRetStatus after DB operation = %d "), lRetStatus);
+ /* Update is NOT ATOMIC!!!
+ * If the earlier aParamDB->SetValueL() was successful, there is a chance that
+ * the config.ini and the DB are out of sync if the operation iConfiguration.WriteSetupL()
+ * is not successful (disk space not enough etc) or when the WriteToFileL() in ParamObject
+ * from iPluginEventHandler->GetParameters() fails.
+ * (WriteToFileL() is called in some destructor when the SCPServer terminates)
+ */
+ if (lRetStatus == KErrNone) {
+ switch (aID) {
+ case RTerminalControl3rdPartySession :: EMaxTimeout:
+ iConfiguration.iMaxTimeout = lNumValue;
+ lRetStatus = iConfiguration.WriteSetupL();
+ Dprint(_L("[CSCPServer]-> After setting EMaxTimeout lRetStatus = %d "), lRetStatus);
+ break;
+ default:
+ TUint16* ptr = const_cast<TUint16*>(aValue.Ptr());
+ TPtr valBuf(ptr, aValue.Length(), aValue.Length());
+ lRetStatus = iPluginEventHandler->GetParameters().Set(aID, valBuf);
+ Dprint(_L("[CSCPServer]-> After setting (%d ) lRetStatus = %d "), aID, lRetStatus);
+ break;
+ }
+ }
+
+ Dprint(_L("[CSCPServer]-> SetBestPolicyL() lRetStatus = %d <<<"), lRetStatus);
+ return lRetStatus;
+}
+
+TInt CSCPServer :: PerformCleanupL(HBufC8* aAppIDBuffer, RArray<const TParamChange>& aChangeArray, RPointerArray<HBufC8>& aParamValArray) {
+ Dprint( (_L("[CSCPServer]-> PerformCleanupL() >>>")));
+
+ if(!aAppIDBuffer) {
+ return KErrArgument;
+ }
+
+ TInt32 lAppCount = aAppIDBuffer->Length();
+
+ if(lAppCount < 1) {
+ return KErrArgument;
+ }
+
+ lAppCount /= sizeof(TInt32);
+
+ TPtr8 bufPtr = aAppIDBuffer->Des();
+
+ TInt lStatus(KErrNone);
+ CSCPParamDBController* lParamDB = CSCPParamDBController :: NewLC();
+
+ RDesReadStream lBufReadStream(bufPtr);
+ CleanupClosePushL(lBufReadStream);
+
+ Dprint(_L("[CSCPServer]-> INFO: Total items received for cleanup is %d"), lAppCount);
+
+ RArray <TInt> lParamIds;
+ CleanupClosePushL(lParamIds);
+
+ TBool lSubOpsFailed = EFalse;
+ HBufC* lDefValueBuf = HBufC :: NewLC(20);
+
+ // Loop through each of the byte packed application ID's specified in aAppIDBuffer and clean them up iteratively
+ for(TInt i=0; i < lAppCount; i++) {
+ TInt32 lAppID = lBufReadStream.ReadInt32L();
+ Dprint((_L("[CSCPServer]-> Initiating cleanup on %d "), lAppID));
+
+
+ lParamIds.Reset();
+ lStatus = lParamDB->ListParamsUsedByAppL(lParamIds, lAppID);
+
+ Dprint(_L("[CSCPServer]-> Status of ListParamsUsedByAppL() = %d"), lStatus);
+
+ TInt lCount = lParamIds.Count();
+
+ Dprint(_L("[CSCPServer]-> lCount=%d"), lCount);
+
+ // Make sure that LockCodeMinChangeTolerance is always cleanedup before LockCodeHistoryBuffer
+ if(lCount > 1) {
+ Dprint(_L("[CSCPServer]-> Updating the cleanup order for EPasscodeMinChangeTolerance and EPasscodeHistoryBuffer if needed..."));
+ TInt lHistBuffIndex = -1;
+ TInt lMinTolIndex = -1;
+
+ for(TInt i=0; i < lCount; i++) {
+ if(lHistBuffIndex >= 0 && lMinTolIndex >= 0) {
+ // If both the indexes have been found, stop the search
+ break;
+ }
+
+ switch(lParamIds[i]) {
+ case RTerminalControl3rdPartySession :: EPasscodeMinChangeTolerance:
+ lMinTolIndex = i;
+ break;
+ case RTerminalControl3rdPartySession :: EPasscodeHistoryBuffer:
+ lHistBuffIndex = i;
+ break;
+ }
+ }
+
+ // This step is required only if both the parameters are marked for cleanup
+ if(lHistBuffIndex >= 0 && lMinTolIndex >= 0) {
+ /* Switch the cleanup order of the two parameters
+ * This step is needed because ListParamsUsedByAppL() always returns the parameters
+ * in Ascending order and because LockCodeMinChangeTolerance is always required to be
+ * cleanedup before LockCodeHistoryBuffer
+ */
+ lParamIds[lHistBuffIndex] = RTerminalControl3rdPartySession :: EPasscodeMinChangeTolerance;
+ lParamIds[lMinTolIndex] = RTerminalControl3rdPartySession :: EPasscodeHistoryBuffer;
+ Dprint(_L("[CSCPServer]-> Switching the cleanup order of EPasscodeHistoryBuffer and EPasscodeMinChangeTolerance"));
+ Dprint(_L("[CSCPServer]-> Old Index of EPasscodeHistoryBuffer=%d"), lHistBuffIndex);
+ Dprint(_L("[CSCPServer]-> Old Index of EPasscodeMinChangeTolerance=%d"), lMinTolIndex);
+ }
+ }
+
+ for(TInt j=0; j < lCount; j++) {
+ TInt lCurrParamID = lParamIds[j];
+ lDefValueBuf->Des().Zero();
+ lDefValueBuf->Des().Format(_L("%d "), 0);
+ // Initialize the default values here...
+ switch(lCurrParamID) {
+ case RTerminalControl3rdPartySession :: EMaxTimeout:
+ // lDefValueBuf already has the default value, 0 initialized...
+ lCurrParamID = ESCPMaxAutolockPeriod;
+ break;
+ case RTerminalControl3rdPartySession :: EPasscodeMinLength:
+ lDefValueBuf->Des().Format(_L("%d"), 4);
+ break;
+ case RTerminalControl3rdPartySession :: EPasscodeMaxLength:
+ lDefValueBuf->Des().Format(_L("%d"), 255);
+ break;
+ default:
+ // lDefValueBuf already has the default value, 0 initialized...
+ break;
+ }
+
+ switch(lCurrParamID) {
+ case RTerminalControl3rdPartySession :: EPasscodeDisallowSpecific: {
+ RPointerArray<HBufC> lDesArr;
+ CleanupClosePushL(lDesArr);
+
+ lStatus = lParamDB->GetValuesL(lCurrParamID, lDesArr, lAppID);
+
+ if(KErrNone == lStatus) {
+ iOverrideForCleanup = ETrue;
+ TInt lDesCount = lDesArr.Count();
+
+ for(TInt k=0; k < lDesCount; k++) {
+ TRAP(lStatus, lStatus = SetParameterValueL(lCurrParamID, lDesArr[k]->Des(), lAppID));
+ if(KErrNone != lStatus) {
+ Dprint(_L("[CSCPServer]-> ERROR: Unable to cleanup parameter %d error %d"), lParamIds[j], lStatus);
+ lSubOpsFailed = ETrue;
+ }
+ }
+
+ iOverrideForCleanup = EFalse;
+ }
+
+ lDesArr.ResetAndDestroy();
+ CleanupStack :: PopAndDestroy(1); // lDesArray
+ }
+ break;
+ default: {
+ iOverrideForCleanup = ETrue;
+ TRAP(lStatus, lStatus = SetParameterValueL(lCurrParamID, lDefValueBuf->Des(), lAppID));
+ iOverrideForCleanup = EFalse;
+
+ if(KErrNone == lStatus) {
+ HBufC8* lTmpBuffer = HBufC8 :: NewL(lDefValueBuf->Length());
+ lTmpBuffer->Des().Copy(lDefValueBuf->Des());
+
+ const TParamChange lChange(lParamIds[j], lTmpBuffer->Des());
+ aChangeArray.AppendL(lChange);
+
+ // No need to destroy lTmpBuffer, it will be cleaned up by the caller (on cleanup of aParamValArray)
+ aParamValArray.AppendL(lTmpBuffer);
+ }
+ }
+ }
+
+ if(KErrNone != lStatus) {
+ Dprint(_L("[CSCPServer]-> ERROR: Unable to cleanup parameter %d error %d"), lParamIds[j], lStatus);
+ lSubOpsFailed = ETrue;
+ }
+ }
+ }
+
+ Dprint( (_L("[CSCPServer]-> PerformCleanupL() <<<")));
+ CleanupStack :: PopAndDestroy(4); // lParamIds lParamDB lBufReadStream lDefValueBuf
+ return (lSubOpsFailed) ? KErrGeneral : KErrNone;
+}
+
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS
+// <<<< ********************** NEW FEATURES ********************
+
+// ================= OTHER EXPORTED FUNCTIONS ==============
+
+ // __ARMI__ /
+
+// ---------------------------------------------------------
+// E32Main EXE entry point
+// Returns: TInt: Process exit value
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+GLDEF_C TInt E32Main()
+ {
+ return CSCPServer::ThreadFunction(NULL);
+ }
+
+
+
+// End of File
+