terminalsecurity/SCP/SCPHistoryPlugin/src/SCPSpecificStringsPlugin.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 13 Oct 2010 15:30:06 +0300
branchRCL_3
changeset 76 3cdbd92ee07b
parent 65 5cc2995847ea
permissions -rw-r--r--
Revision: 201039 Kit: 201041

/*
* 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 <e32base.h>
#include <e32std.h>
#include <ecom/implementationproxy.h>
#include <SCPParamObject.h>

#include "SCPSpecificStringsPlugin.h"
#include <SCPHistoryPluginLang.rsg>
#include "SCP_IDs.h"
#include <featmgr.h>

// ============================= LOCAL FUNCTIONS  =============================

// ============================= MEMBER FUNCTIONS =============================

// ----------------------------------------------------------------------------
// CSCPSpecificStringsPlugin::NewL
// Two-phased contructor
// (static, may leave)
// Status : Approved
// ----------------------------------------------------------------------------
//
CSCPSpecificStringsPlugin* CSCPSpecificStringsPlugin::NewL()
    {
	CSCPSpecificStringsPlugin* self = new ( ELeave ) CSCPSpecificStringsPlugin();
	CleanupStack::PushL( self );
	self->ConstructL();
	CleanupStack::Pop( self );
	
    Dprint ( ( _L( "( 0x%x ) CSCPSpecificStringsPlugin::NewL()" ), self ) );

    return self;
    }

// ----------------------------------------------------------------------------
// CSCPSpecificStringsPlugin::CSCPSpecificStringsPlugin
// Constructor
// Status : Approved
// ----------------------------------------------------------------------------
//
CSCPSpecificStringsPlugin::CSCPSpecificStringsPlugin()
   
    {
    Dprint ( ( _L( "CSCPSpecificStringsPlugin::CSCPSpecificStringsPlugin()" ) ) );
    return;
    }

// ----------------------------------------------------------------------------
// CSCPSpecificStringsPlugin::ConstructL
// 2nd phase construction
// (may leave)
// Status : Approved
// ----------------------------------------------------------------------------
//
void CSCPSpecificStringsPlugin::ConstructL()
    {
    
    FeatureManager::InitializeLibL();
	if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
	{
    	FeatureManager::UnInitializeLib();
   		User::Leave( KErrNotSupported );
  	}
   	FeatureManager::UnInitializeLib();
    return;
    }
    
// ----------------------------------------------------------------------------
// CSCPSpecificStringsPlugin::HandleEvent
// 
// 
// Status : Approved
// ----------------------------------------------------------------------------
//    
CSCPParamObject* CSCPSpecificStringsPlugin::HandleEvent( TInt aID, CSCPParamObject& aParam )
	{	
	
	// Make the ParamObject for success ack, Delete later
	CSCPParamObject* retParams = NULL;

	TBool errRaised;
	errRaised = EFalse;
		
	if ( iFs == NULL )
	    {
	    return NULL; // Eventhandler not available
	    }

	// check for Case
	switch ( aID )
	    {
		case ( KSCPEventValidate ) :
    		{   		
			TBool specificstringscheck;
			
			// Get params
			CSCPParamObject& config = iEventHandler->GetParameters();
			
			// Check if validation is required.
			if ( config.Get( ( RTerminalControl3rdPartySession::EPasscodeCheckSpecificStrings), 
				  specificstringscheck ) !=  KErrNone )
				   specificstringscheck = EFalse;

			 if ( specificstringscheck )
			    {
			 	// Check for specific strings			 	
			 	
				// Get the configFile's path.
				// If this fails, there is something badly wrong(Private folder is not there)
				TInt errSCF = SetConfigFile ();
				if (errSCF != KErrNone)
				    {
					errRaised = ETrue;
					break; // Break out from Case!
				    }
			 	
			 	// Get the password from the paramObject
	     		TBuf<KSCPPasscodeMaxLength> securitycode;
	            if ( aParam.Get( KSCPParamPassword, securitycode ) != KErrNone )
                    {
                	// Nothing to do anymore
                   	Dprint( (_L("CSCPSpecificStringsPlugin::HandleEvent()\
                   	ERROR: KSCPEventPasswordChanged/KSCPParamPassword is  != KErrNone") ));
                	errRaised = ETrue;
					break; // Break out from the Case!;
                    }			 	
			 	
			 	TBool forbiddensecuritycode = EFalse;
			 	
			 	TInt errCSS = CheckSpecificStrings ( securitycode, forbiddensecuritycode );
			 	if (errCSS != KErrNone)
				    {
					errRaised = ETrue;
					break; // Break out from Case!
    				}
			 	
			 	if ( forbiddensecuritycode )
			    	{
			 		// Word was blacklisted!
					// Get the filesystem for Resource
					// If fail, bail out!
					TInt errgGR = GetResource();
					if (errgGR != KErrNone)
					    {
						errRaised = ETrue;
						break; // Break out from the For!
					    }
			 	
			 		// Prompt buf, iNote can show only 97 chars,
					// without ... markings.
					HBufC* hbuf = NULL;
					
					TRAP_IGNORE(
					    hbuf = LoadAndFormatResL( R_SET_SEC_CODE_PERSONAL );
		                );		                

                    // Create the result-object to return
				    TRAPD( err, retParams  = CSCPParamObject::NewL() );
                    
                    if ( err == KErrNone )
				        {
			            retParams->Set( KSCPParamStatus, KErrSCPInvalidCode );
    		            retParams->Set( KSCPParamAction, KSCPActionShowUI );
	    	            retParams->Set( KSCPParamUIMode, KSCPUINote );
		                
		                if ( hbuf != NULL )
		                    {
		                    TPtr ptr = hbuf->Des();
		                    retParams->Set( KSCPParamPromptText, ptr );
		                    delete hbuf;
		                    }
				        }    					        
			 	    }			 	    		 	
			    } // end of specificstringscheck

			break;
		    } // End of KSCPEventValidate

	    case ( KSCPEventRetrieveConfiguration ):
	        {
	        // This event is sent when a client wishes to retrieve the value for the given parameter.
	        // None of the parameters, which handle the string-buffer cannot be retrieved by anyone,
	        // so we'll return KErrNotSupported. Note that EPasscodeCheckSpecificStrings is OK to get.
	        
	        // Get the ID from the paramObject   
	        TInt paramID = -1;    
			if ( aParam.Get( KSCPParamID, paramID ) != KErrNone )
			    {
				// Nothing to do anymore
				break;
    			}   
			    
			if ( ( paramID ==  RTerminalControl3rdPartySession::EPasscodeDisallowSpecific )
				||  ( paramID ==  RTerminalControl3rdPartySession::EPasscodeAllowSpecific)
				||  ( paramID ==  RTerminalControl3rdPartySession::EPasscodeClearSpecificStrings) )
			    {
	            TRAPD( err, retParams  = CSCPParamObject::NewL() );
	            if ( err == KErrNone )
	                {
	                Dprint ( ( _L( "CSCPSpecificStringsPlugin::HandleEvent():\
	                    Get not supported for %d" ), paramID ) );
	                retParams->Set( KSCPParamStatus, KErrNotSupported );
	                }
	            else
	                {
	                Dprint ( ( _L( "CSCPSpecificStringsPlugin::HandleEvent():\
	                    ERROR: Cannot create paramObject" ) ) );
	                }
	            }
	        break;
	        }

		// same for All plugins
		case ( KSCPEventConfigurationQuery ):
    		{   		
			TInt paramID = -1; 

			// Get the ID from the paramObject      
			if ( aParam.Get( KSCPParamID, paramID ) != KErrNone )
			    {
				// Nothing to do anymore
				break;
			    }            

			if ( paramID == (RTerminalControl3rdPartySession::EPasscodeCheckSpecificStrings)
				||  paramID ==  (RTerminalControl3rdPartySession::EPasscodeDisallowSpecific)
				||  paramID ==  (RTerminalControl3rdPartySession::EPasscodeAllowSpecific)
				||  paramID ==  (RTerminalControl3rdPartySession::EPasscodeClearSpecificStrings) )
			    {						
				// OK, we're interested
                TRAPD( err, retParams  = CSCPParamObject::NewL() );
                if ( err != KErrNone )
                    {
                    break; // Nothing we can do now
                    }
                                
				TInt retStatus = KErrNone;
				
			    if ( paramID != RTerminalControl3rdPartySession::EPasscodeCheckSpecificStrings )
			        {
        		    // Set the storage attribute, so the server won't save the value,
        		    // we'll do it ourselves.
        			retParams->Set( KSCPParamStorage, KSCPStoragePrivate );			        
			        }

				switch ( paramID )
				    {
					case ( RTerminalControl3rdPartySession::EPasscodeCheckSpecificStrings ):
					    {
						// 1015				
						TInt paramValue;
						if ( (aParam.Get( KSCPParamValue, paramValue ) != KErrNone) ||
							 ( paramValue < 0 ) || 	( paramValue > 1 ) ) 
						       retStatus = KErrArgument;
						
					    break;
					    }
					
					// 1016
					// Handle param change for strings to block
					case ( RTerminalControl3rdPartySession::EPasscodeDisallowSpecific ):
					    {
						// Get the params value's length
						// If param length is not correct, there's something very wrong. out
						TInt paramlength = aParam.GetParamLength( KSCPParamValue );
						if ( paramlength <= 0)
						    {
							retStatus = KErrArgument;
							break; // from case!
						    }

						HBufC* paramvaluebuf = NULL;
						TRAPD( err, paramvaluebuf = HBufC::NewL( paramlength ) );
						if ( err != KErrNone )
						    {
						    retStatus = err;
						    break;
						    }
						    
						TPtr paramptr = paramvaluebuf->Des();
						aParam.Get( KSCPParamValue, paramptr );

						// Check for basic test
						if ( IsNotValidWord ( paramptr ) )
						    {
							retStatus = KErrArgument;
							delete paramvaluebuf;
							break;
    						}
    						
						// Send them to parser and store them
						TInt errgPS = KErrNone;
						TRAPD( err2, errgPS = ParseAndStoreL( paramptr ) );
						if ( err2 != KErrNone )
						    {
						    errgPS = err2;
						    }
						
						delete paramvaluebuf;
						
						if (errgPS != KErrNone)
						    {
							if (errgPS == KErrArgument)
							    {
								retStatus = KErrArgument;
								break; // from case!
							    }
	
							errRaised = ETrue;
							break; // Break out.
						    } 
					    break;
					    }
					

					// 1017
					// Handle param change for strings exclude from the list
					case ( RTerminalControl3rdPartySession::EPasscodeAllowSpecific ):
					    {
	
						// Get the params value's length
						// If param length is not correct, there's something very wrong. out
						TInt paramlength = aParam.GetParamLength( KSCPParamValue );
						if ( paramlength <= 0)
						    {
							retStatus = KErrArgument;
							break; // from case!
						    }
																		
						HBufC* paramvaluebuf = NULL;
						TRAPD( err, paramvaluebuf = HBufC::NewL( paramlength ) );
						if ( err != KErrNone )
						    {
						    retStatus = err;
						    break;
						    }
						    
						TPtr paramptr = paramvaluebuf->Des();
						aParam.Get( KSCPParamValue, paramptr );

						// Check for basic test
						if ( IsNotValidWord ( paramptr ) )
						    {
							retStatus = KErrArgument;
							delete paramvaluebuf;
							break;
						    }
						    
						// Send the word to remover and gets them off the list
						TInt errgPR = KErrNone;
						TRAPD( err2, errgPR = ParseAndRemoveL( paramptr ) );
						if ( err2 != KErrNone )
						    {
						    errgPR = err2;
						    }
						
						delete paramvaluebuf;
						
						if (errgPR != KErrNone)
						    {
							if (errgPR == KErrArgument)
							    {
							    retStatus = KErrArgument;
								break; // from case!
							    }
	
							errRaised = ETrue;
							break; // Break out.
						    } 												
						
					    break;
					    }												
					
					case ( RTerminalControl3rdPartySession::EPasscodeClearSpecificStrings ):
					    {					
						// 1018, Flush the config file
						TInt paramValue;
						if ( (aParam.Get( KSCPParamValue, paramValue ) != KErrNone) ||
							 ( paramValue < 0 ) || 	( paramValue > 1 ) )
						    {
                            retStatus = KErrArgument;
						    }						     
						
						if (paramValue == 1 && retStatus == KErrNone) 
						    {
						    TRAP_IGNORE( FlushConfigFileL() );
						    }
						    
						break;
					    }							
    				} // End of switch                          

				retParams->Set( KSCPParamStatus, retStatus );
			    }
			else
			    {
				retParams = NULL;
			    }		
		         
			break;
		    } //End of KSCPEventConfigurationQuery Case

        case ( KSCPEventReset ):
              {
              // Reset the configuration for this plugin.
              TRAP_IGNORE( FlushConfigFileL() );
              
              break;
              }

	} // End of  switch ( aID )

	// Check if Any errors were raised and handle it
	if (errRaised) 
        {
        if ( retParams != NULL )
            {
            delete retParams;
            }
        retParams = NULL;
        }

	return retParams; 
	}

// ----------------------------------------------------------------------------
// CSCPSpecificStringsPlugin::SetEventHandler
// SetEventHandler
// 
// Status : Approved
// ----------------------------------------------------------------------------
//    
void CSCPSpecificStringsPlugin::SetEventHandler( MSCPPluginEventHandler* aHandler )
	{
	iEventHandler = aHandler;
	
	iFs = &(iEventHandler->GetFsSession());
	}	

// ----------------------------------------------------------------------------
// CSCPSpecificStringsPlugin::~CSCPSpecificStringsPlugin
// Destructor
// Status : Approved
// ----------------------------------------------------------------------------
//
CSCPSpecificStringsPlugin::~CSCPSpecificStringsPlugin()
    {
	Dprint( (_L("CSCPSpecificStringsPlugin::~CSCPSpecificStringsPlugin()") ));
    
	iRf.Close();   
        	
	return;
    }



// ----------------------------------------------------------------------------
// CSCPSpecificStringsPlugin::GetResource
// GetResource
// Status : Approved
// ----------------------------------------------------------------------------
//

TInt CSCPSpecificStringsPlugin::GetResource()
    {   
 	Dprint( (_L("CSCPSpecificStringsPlugin::GetResource()") ));
	// The resource has to be loaded manually since it is not an application.
    
	TFileName resourceFile;
	resourceFile.Append( KDriveZSpecific );
	resourceFile.Append( SCPSpecificStringsPluginSrcFile );
	BaflUtils::NearestLanguageFile( *iFs, resourceFile );
	TRAPD( err, iRf.OpenL( *iFs, resourceFile ) );

	if ( err == KErrNone )
	    {
		TRAP( err, iRf.ConfirmSignatureL() );
	    }          
 
    return err;       
    }


// ----------------------------------------------------------------------------
// CSCPSpecificStringsPlugin::LoadResourceLC
// GetResource
// Status : Approved
// ----------------------------------------------------------------------------
//
HBufC16* CSCPSpecificStringsPlugin::LoadResourceLC ( TInt aResId )
    {
	Dprint( (_L("CSCPSpecificStringsPlugin::LoadResourceLC()") ));

	// load the actual resource
     HBufC8* readBuffer = iRf.AllocReadLC( aResId );
    // as we are expecting HBufC16...
     const TPtrC16 ptrReadBuffer( (TText16*) readBuffer->Ptr(),
                                 ( readBuffer->Length() + 1 ) >> 1 );
    HBufC16* textBuffer=HBufC16::NewL( ptrReadBuffer.Length() );    
    *textBuffer=ptrReadBuffer;
    CleanupStack::PopAndDestroy( readBuffer ); // readBuffer
    CleanupStack::PushL( textBuffer );
  	return textBuffer;
    }




// ----------------------------------------------------------------------------
// CSCPSpecificStringsPlugin::SetConfigFile
// SetConfigFile
// Status : Approved
// ----------------------------------------------------------------------------
//
TInt CSCPSpecificStringsPlugin::SetConfigFile()
    {	
	Dprint( (_L("CSCPSpecificStringsPlugin::SetConfigFile()") ));
	TRAPD( err, iEventHandler->GetStoragePathL( iCfgFilenamepath ) );
	if ( err != KErrNone )
        {
		Dprint( (_L("CSCPSpecificStringsPlugin::SetConfigFile:\
		ERROR: Failed to get storage path: %d"), err ));             
		return err;
	    }
	iCfgFilenamepath.Append( KConfigFileSpecific );
	return err;
    }

// ----------------------------------------------------------------------------
// CSCPSpecificStringsPlugin::CheckSpecificStrings
// CheckSpecificStrings
// Status : Approved
// ----------------------------------------------------------------------------
//
TInt CSCPSpecificStringsPlugin::CheckSpecificStrings( TDes& aSecuritycode, 
													  TBool& aForbiddenSecurityCode )
    {
	Dprint( (_L("CSCPSpecificStringsPlugin::CheckSpecificStrings()") ));
	// Default is not blocklistedword
	aForbiddenSecurityCode = EFalse;
	
	// get GetSpecificStringsArray
	CDesCArrayFlat*  array = new CDesCArrayFlat(1);
	TInt err = KErrNone;
	
	if ( array == NULL )
	    {
	    err = KErrNoMemory;
	    }
	else
	    {
	    TRAPD( err2, err = GetSpecificStringsArrayL( *array ) );
	    if ( err2 != KErrNone )
	        {
	        err = err2;
	        }
	    }
	
	if (err != KErrNone)
	    {
		// Kill local array
		if ( array != NULL )
		    {
		    array->Reset();    
		    delete array;
		    }
		    		
		return err;
	    }

	// check for match
	TBuf<KSCPPasscodeMaxLength> arrayItem;
	// We use the uppercase version of the given string while checking
	TBuf<KSCPPasscodeMaxLength> secCodeBuf;
	secCodeBuf = aSecuritycode;
	secCodeBuf.UpperCase();

	// Set the historyobject
	for (TInt i=0; i < array->Count(); i++)
    	{
		arrayItem.Zero();
		arrayItem = array->MdcaPoint(i);
		arrayItem.UpperCase();
		// Check if this string causes the password to be invalid
		// the strings are matched by a case-insensitive substring match.
		if ( secCodeBuf.Find( arrayItem ) != KErrNotFound )
		    {
			aForbiddenSecurityCode = ETrue;
			break; // Out from for
		    }
    	}
    	
	// Kill local array
	array->Reset();
	delete array;
	return err; 
    }

// ----------------------------------------------------------------------------
// CSCPSpecificStringsPlugin::ParseAndStoreL
// ParseAndStore ForbiddenSecurityCodes
// Status : Approved
// ----------------------------------------------------------------------------
//
TInt CSCPSpecificStringsPlugin::ParseAndStoreL( TDes& aForbiddenSecurityCodes )
    {
	Dprint( (_L("CSCPSpecificStringsPlugin::ParseAndStore()") ));
	// Set The file environment
	TInt errSC = SetConfigFile ();
	if (errSC != KErrNone) return errSC;
	

	// Make array for data
	CDesCArrayFlat*  array = new (ELeave) CDesCArrayFlat(1);
	CleanupStack::PushL( array );

	// Read the previous wordlist.
	// Reading might fall for NotFound, don't care
	TInt errGS = GetSpecificStringsArrayL( *array );
	
	if (errGS != KErrNone && errGS != KErrNotFound  )
	    {
		// Kill local array
		array->Reset();
		CleanupStack::PopAndDestroy( array );
		return errGS;
	    }
		
	// Parse the ; separated values into array
	TLex16 lex (aForbiddenSecurityCodes);
	lex.Mark();
	while(!lex.Eos())
	    {
		while(lex.Peek() != ';' && !lex.Eos() ) lex.Inc();

		array->AppendL(lex.MarkedToken());
		lex.Inc();
		lex.Mark();
		}
		
		
	// Check for duplicates!
	RemoveDuplicateWords( *array );

	// Store Array
	// Make the ParamObject
	CSCPParamObject* forbiddensecuritycodeobject = CSCPParamObject::NewL();
	CleanupStack::PushL( forbiddensecuritycodeobject );
	TBuf<KSCPPasscodeMaxLength> arrayItem;

	// Append the Data 
	for (TInt i=0 ; i < array->Count(); i++)
		{
		arrayItem =  array->MdcaPoint(i);
		forbiddensecuritycodeobject->Set( KSpecificStringsParamBase+i,arrayItem);
		arrayItem.Zero();
		}

	// Set the Counter param
	forbiddensecuritycodeobject->Set( KSpecificStringsCounterParamID,array->Count());
			
	//Write
	TRAPD( err, forbiddensecuritycodeobject->WriteToFileL( iCfgFilenamepath, iFs ) );
	if (  err != KErrNone  )
	    {
		Dprint( (_L("CSCPSpecificStringsPlugin::ParseAndStore(): WARNING:\
		failed to write plugin configuration: %d"), err )); 
    	}

    CleanupStack::PopAndDestroy( forbiddensecuritycodeobject );
    
    // Kill the array
	array->Reset();
	CleanupStack::PopAndDestroy( array );
    
	return err;
}


// ----------------------------------------------------------------------------
// CSCPSpecificStringsPlugin::FlushConfigFileL
// FlushConfigFile
// Status : Approved
// ----------------------------------------------------------------------------
//
TInt CSCPSpecificStringsPlugin::FlushConfigFileL()
    {
	Dprint( (_L("CSCPSpecificStringsPlugin::FlushConfigFile()") ));

	SetConfigFile();

	CFileMan* fileMan = CFileMan::NewL( *iFs );
	CleanupStack::PushL( fileMan );

	TInt ret= fileMan->Delete( iCfgFilenamepath, 0 );

	CleanupStack::PopAndDestroy( fileMan ); // fileMan
	return ret;
    }


// ----------------------------------------------------------------------------
// CSCPSpecificStringsPlugin::GetSpecificStringsArrayL
// Reads the historyconfig file and retrieves the forbidden data
// Status : Approved
// ----------------------------------------------------------------------------
//
TInt CSCPSpecificStringsPlugin::GetSpecificStringsArrayL( CDesCArrayFlat& array )
{   

	Dprint( (_L("CSCPSpecificStringsPlugin::GetSpecificStringsArray()") ));
	
	 TBuf<KSCPPasscodeMaxLength> arrayItem;
	 TInt counter;
	 TInt err = KErrNone;
	 
	// Make the ParamObject
	CSCPParamObject* forbiddensecuritycodeobject = CSCPParamObject::NewL();
	CleanupStack::PushL( forbiddensecuritycodeobject );

	TRAP( err, forbiddensecuritycodeobject->ReadFromFileL( iCfgFilenamepath, iFs ) );
	if ( err != KErrNone ) 
	{
			// Reading from history fails. 
			Dprint( (_L("CSCPHistoryPlugin::GetHistoryArray():\
			failed to read plugin configuration: %d"), err )); 
			CleanupStack::PopAndDestroy( forbiddensecuritycodeobject );
			return err;
	}

	// Get the historyCount
	forbiddensecuritycodeobject->Get(KSpecificStringsCounterParamID,counter);

	// Loop them into array
	for (TInt i = 0 ; i < counter ; i ++)
	{
		forbiddensecuritycodeobject->Get(KSpecificStringsParamBase+i,arrayItem);
		array.AppendL(arrayItem);
		arrayItem.Zero();
	}

    CleanupStack::PopAndDestroy( forbiddensecuritycodeobject );
	return err;
	
}

// ----------------------------------------------------------------------------
// CSCPSpecificStringsPlugin::IsNotValidWord
// Checks wheater the given buf contains any illegal chars like ., <space>
// ; char is granted due to a delimiter role. ETrue means buf is no good!
// Status : Approved
// ----------------------------------------------------------------------------
//
TBool CSCPSpecificStringsPlugin::IsNotValidWord ( TDes& aForbiddenSecurityCodes )
{
	
	Dprint( (_L("CSCPSpecificStringsPlugin::IsNotValidWord()") ));
	// If so, there is a problem ETrue!!
	TBool ret;
	TChar now,previous;		// at hand & prevous char
	ret = EFalse;
	now = 0;
	previous = 0;
	
	// Go through the word
	for (TInt i=0; i < aForbiddenSecurityCodes.Length(); i++)
	{
		
		// Get the current Char to examine
		now =  static_cast<TChar>( aForbiddenSecurityCodes[i] );
		// And the previous
		if ( i >= 1 ) 
		    {
		    previous = static_cast<TChar>( aForbiddenSecurityCodes[i-1] );
		    }
	
		// Check for Sapce!
		if ( now.IsSpace() || now < 1 || now > 126 )
		{
			// Space or Invalid character found, bad, out!
			ret = ETrue;
			break;
			
		}
		
		
		/*if (! now.IsAlphaDigit() )
		{
				// Was not alphadigit. Anyhow ; must come through
				if ( now != ';'  )
				{
					// bad, out!
					ret = ETrue;
					break;
				}
				
				if ( now == ';' && previous == ';'  )
				{
					// bad, out!
					ret = ETrue;
					break;
				}
		
		}*/

	} // EOFor
	return ret;
}

// ----------------------------------------------------------------------------
// CSCPSpecificStringsPlugin::RemoveDuplicateWords
// Checks wheater there are duplicate words in the array, removes them!
// Status : Approved
// ----------------------------------------------------------------------------
//
void CSCPSpecificStringsPlugin::RemoveDuplicateWords( CDesCArrayFlat& array )
{
	Dprint( (_L("CSCPSpecificStringsPlugin::RemoveDuplicateWords()") ));
	// check for match
	TBuf<KSCPPasscodeMaxLength> arrayItemAt;
	TBuf<KSCPPasscodeMaxLength> arrayItemNext;
	TInt arraycounter =0;
	while (arraycounter < array.Count())
	{
		// Get the item from array.
		arrayItemAt =  array.MdcaPoint(arraycounter);	
		
		// search the rest for match
		for (TInt n = 1 + arraycounter ; n < array.Count() ; n++)
		{		
			arrayItemNext = array.MdcaPoint(n);
			if (arrayItemAt.Compare(arrayItemNext) == KErrNone)
			{
				// Delete 
				array.Delete(n);
				n--; 
				
			}
		}
		arraycounter++;
	
	}

}


// ----------------------------------------------------------------------------
// CSCPSpecificStringsPlugin::ParseAndRemoveL
// Parses And Removes ForbiddenSecurityCodes from ini file
// Status : Approved
// ----------------------------------------------------------------------------
//
TInt CSCPSpecificStringsPlugin::ParseAndRemoveL( TDes& aForbiddenSecurityCodes )
    {
	Dprint( (_L("CSCPSpecificStringsPlugin::ParseAndRemoveL()") ));
	// Set The file environment
	TInt errSC = SetConfigFile ();
	if (errSC != KErrNone) return errSC;


	// Make array for data
	CDesCArrayFlat*  arraycurrent = new (ELeave) CDesCArrayFlat(1);
	CleanupStack::PushL( arraycurrent );
	
	// Read the previous wordlist.
	// Reading might fall for NotFound, get out, nothing to do.
	if ( GetSpecificStringsArrayL( *arraycurrent ) == KErrNotFound  )
	    {
	    arraycurrent->Reset();
	    CleanupStack::PopAndDestroy( arraycurrent );
	    return KErrNone;
	    }

	// Make array for data for wordlist to be removed
	CDesCArrayFlat*  arrayremoved = new (ELeave) CDesCArrayFlat(1);
	CleanupStack::PushL( arrayremoved );
	
	// Parse the ; separated values into array from given wordlist
	TLex16 lex (aForbiddenSecurityCodes);
	lex.Mark();
	while(!lex.Eos())
	{
		while(lex.Peek() != ';' && !lex.Eos() ) lex.Inc();

			arrayremoved->AppendL(lex.MarkedToken());
			lex.Inc();
			lex.Mark();
		}
		
	// Remove possible duplicates in wordlist
	RemoveDuplicateWords( *arrayremoved );
	
	// Make the ParamObject
	CSCPParamObject* forbiddensecuritycodeobject = CSCPParamObject::NewL();
	CleanupStack::PushL( forbiddensecuritycodeobject );
	
	TBuf<KSCPPasscodeMaxLength> arrayItemcurrent;
	TBuf<KSCPPasscodeMaxLength> arrayItemremove;
	TInt addedcounter,removedcounter,currentItemCounter,err;
	TBool itemremovedexlude,itemremovecurrent;
	itemremovedexlude = EFalse;
	itemremovecurrent = EFalse;
	addedcounter = 0;
	removedcounter = 0;
	err = 0;
	
	// Remember the current situation before exluding.
	currentItemCounter = arraycurrent->Count();
	
	// Loop the main array
	while (addedcounter < arraycurrent->Count())
	{
		// Get the item from current spesific wordarray.
		arrayItemcurrent =  arraycurrent->MdcaPoint(addedcounter);	
		while (removedcounter < arrayremoved->Count())
		{
			
			arrayItemremove =  arrayremoved->MdcaPoint(removedcounter);
			if(arrayItemcurrent.CompareC(arrayItemremove) == KErrNone)
			{
				arrayremoved->Delete(removedcounter);
				arraycurrent->Delete(addedcounter);
				itemremovedexlude = ETrue;
				itemremovecurrent = ETrue;
			}
			if (itemremovedexlude) itemremovedexlude = EFalse;
			else removedcounter++;
	
		}
	
		if (itemremovecurrent) itemremovecurrent = EFalse;
		else addedcounter++;
		removedcounter = 0;
	}
	
	// Check wheather there has been eny changes in the current array (removes)
	if (currentItemCounter != arraycurrent->Count() )
	    {
		// All of items were removed, flush the file
		if ( arraycurrent->Count() == 0 )
		    {
		    TRAP_IGNORE( FlushConfigFileL() );
		    }
		else
		    {
			// Reuse
			arrayItemcurrent.Zero();
			// Set the object with fixed array
			for (TInt n = 0; n < arraycurrent->Count() ; n++)
			{
				// Get the item from current spesific wordarray.
				arrayItemcurrent =  arraycurrent->MdcaPoint(n);	
				forbiddensecuritycodeobject->Set( KSpecificStringsParamBase+n,arrayItemcurrent);
			}
		
			// Set the Counter param
			forbiddensecuritycodeobject->Set( KSpecificStringsCounterParamID,arraycurrent->Count());

			//Write
			TRAP( err, forbiddensecuritycodeobject->WriteToFileL( iCfgFilenamepath, iFs ) );
			if (  err != KErrNone  )
			    {
				Dprint( (_L("CSCPSpecificStringsPlugin::ParseAndRemoveL(): WARNING:\
				failed to write plugin configuration: %d"), err )); 
			    }			
		    }		
	    }
	
	
	CleanupStack::PopAndDestroy( forbiddensecuritycodeobject );
	
	// Kill arrays
	arrayremoved->Reset();
	CleanupStack::PopAndDestroy( arrayremoved );
	
	arraycurrent->Reset();
	CleanupStack::PopAndDestroy( arraycurrent );			    
 
	return err;
    }
    
    
// ----------------------------------------------------------------------------
// CSCPSpecificStringsPlugin::LoadAndFormatResL
// Load the given resouce, and format the string according to the TInt parameters
// if given.
// 
// Status : Approved
// ----------------------------------------------------------------------------
//
HBufC* CSCPSpecificStringsPlugin::LoadAndFormatResL( TInt aResId, TInt* aParam1, TInt* aParam2 )
    {
    HBufC16* resource = NULL;
    HBufC* hbuf = NULL;
    
    resource = LoadResourceLC( aResId );
    TInt allocLen = 0;
    if ( aParam1 != NULL )
        {
        allocLen += KSCPMaxIntLength;
        }
    if ( aParam2 != NULL )
        {
        allocLen += KSCPMaxIntLength;
        }
                
	hbuf = HBufC::NewL( resource->Length() + allocLen );
	
	if ( ( aParam1 == NULL ) && ( aParam2 == NULL ) )
	    {
	    hbuf->Des().Copy( resource->Des() );
	    }
	else
	    {
	    if ( aParam1 == NULL )
	        {
	        hbuf->Des().Format( resource->Des(), *aParam2 );
	        }
	    else if ( aParam2 == NULL )
	        {
	        hbuf->Des().Format(resource->Des(), *aParam1 );
	        }
	    else
	        {
	        hbuf->Des().Format(resource->Des(), *aParam1, *aParam2 );
	        }	    
	    }
								    
	CleanupStack::PopAndDestroy( resource );
	return hbuf;
    }    

// End of File