lowlevellibsandfws/apputils/bsul/inc/clientmessage.h
changeset 0 e4d67989cc36
child 39 4393da0c39b5
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Wrapper around RMessage2 that provides message validation and error handling
       
    15 // to improve robustness of system servers under IPC attack
       
    16 // 
       
    17 //
       
    18 
       
    19 #if !defined(CLIENTMESSAGE_H)
       
    20 #define CLIENTMESSAGE_H
       
    21 
       
    22 #include <e32std.h>
       
    23 #include <e32base.h>
       
    24 #include <e32debug.h>
       
    25 #include <babitflags.h>
       
    26 
       
    27 namespace BSUL
       
    28 	{
       
    29 	
       
    30 	//Version number of the client server framework code
       
    31 	const TInt KClientMessageVersion = 0x1;
       
    32 	
       
    33 	//Forward Declarations
       
    34 	class CMessageParameterBase;	
       
    35 	
       
    36 	//Const Declarations
       
    37 
       
    38 	/**
       
    39 	Returned to caller to indicate that the requested message number is not
       
    40 	supported by the current server
       
    41 	@publishedPartner
       
    42 	@released
       
    43 	*/
       
    44 	const TInt KErrInvalidFunction 		= -1004; 
       
    45 	
       
    46 	/**
       
    47 	Returned to caller if a message is passed in containing a non-descriptor
       
    48 	parameter which doesn't meet the constraints specified in the schema
       
    49 	@publishedPartner
       
    50 	@released
       
    51 	*/
       
    52 	const TInt KErrBadParameter 		= -1005; 
       
    53 	
       
    54 	/**
       
    55 	Returned to caller in UREL mode when the server attempts to call a 
       
    56 	CMessageParameterBase function which is not defined for the given
       
    57 	parameter type. E.g. calling GetIntL() on a Descriptor parameter.
       
    58 	@publishedPartner
       
    59 	@released
       
    60 	*/
       
    61 	const TInt KErrWrongParameterType 		= -1006; 
       
    62 	
       
    63 	/**
       
    64 	Returned to caller in UREL mode when a message is found to be
       
    65 	incorrectly defined in the message schema. 
       
    66 	@publishedPartner
       
    67 	@released
       
    68 	*/
       
    69 	const TInt KErrBadMessageSchema			= -1007; 
       
    70 	
       
    71 	
       
    72 	/**
       
    73 	Returned to caller to indicate that the requested parameter has not yet
       
    74 	been validated
       
    75 	@publishedPartner
       
    76 	@released
       
    77 	*/
       
    78 	const TInt KErrNotValidated			= -1008; //Server internal error
       
    79 	
       
    80 	/**
       
    81 	Returned to caller to indicate that the ClientMessage framework has
       
    82 	not yet been initialised
       
    83 	@publishedPartner
       
    84 	@released
       
    85 	*/
       
    86 	const TInt KErrNotInitialised		= -1009; //Server internal error
       
    87 	
       
    88 	
       
    89 	//Enum Declarations
       
    90 	
       
    91 	/**
       
    92 	This is the list of Panic codes used by the ClientMessage framework
       
    93 	@publishedPartner
       
    94 	@released
       
    95 	*/
       
    96 	enum
       
    97 		{
       
    98 		/**This panic is raised in UDEB mode when the server attempts to call a 
       
    99 		CMessageParameterBase function which is not defined for the given
       
   100 		parameter type. E.g. calling GetIntL() on a Descriptor parameter.
       
   101 		*/
       
   102 		ECMPanicWrongParameterType = 0,
       
   103 		
       
   104 		/**This panic is raised when the server attempts to read from a
       
   105 		descriptor in the clients process and supplies a target descriptor
       
   106 		that is smaller than the client descriptor.
       
   107 		*/
       
   108 		ECMPanicBadDescriptor,
       
   109 		
       
   110 		/**This panic is raised when a TParameterDetails structure for a 
       
   111 		given parameter is incorrectly defined in the message schema
       
   112 		*/
       
   113 		ECMPanicBadMessageSchema
       
   114 		};	
       
   115 	
       
   116 	/**
       
   117 	This Enum lists the currently supported Parameter types.  
       
   118 	These enum values are used as indices to the Parameter Factory Function
       
   119 	which instantiates the appropriate CMessageParammeterBase derived
       
   120 	object to represent a given message parameter.
       
   121 	@publishedPartner
       
   122 	@released
       
   123 	*/
       
   124 	enum TParamType
       
   125 		{
       
   126 		EParamNull = 0,
       
   127 		EParamInt,
       
   128 		EParamDes8Read,
       
   129 		EParamDes8,
       
   130 		EParamPckg,
       
   131 		EParamDes16Read,
       
   132 		EParamDes16,
       
   133 		EParamPtr
       
   134 		};
       
   135 	
       
   136 	/**
       
   137 	This enum lists the currently supported flags that can be passed to the server
       
   138 	in TClientMessageServerData::iFlags.  Note that internally this value is stored
       
   139 	in a TBitFlags32 type but this type cannot be statically initialised in a dll 
       
   140 	so the value is passed to the framework in a TInt. The bottom 16 bit flags are 
       
   141 	reserved for the framework's internal use.
       
   142 
       
   143 	@publishedPartner
       
   144 	@released
       
   145 	*/
       
   146 	enum TServerFlags
       
   147 		{
       
   148 		/** Default empty flag */
       
   149 		ESrvFlagNone = 0,
       
   150 		/** Setting this flag indicates that for bad message errors, request 
       
   151 		should be completed with error code rather than panicking the client */
       
   152 		ESrvFlagDoNotPanicClientOnBadMessageErrors = 0x40000000,
       
   153 		/** Indicates that bad messages should be logged in UDEB */
       
   154 		ESrvFlagLogBadMessages = 0x80000000
       
   155 		};
       
   156 	
       
   157 	//Typedef Declarations
       
   158 	
       
   159 	/**
       
   160 	This typedef is used to simplify the declaration of custom
       
   161 	parameter validation functions
       
   162 	@publishedPartner
       
   163 	@released
       
   164 	*/
       
   165 	typedef void (*TCustomValidationFn)(CMessageParameterBase* aParameter);
       
   166 
       
   167 	
       
   168 	
       
   169 	//Struct Declarations
       
   170 		
       
   171 	/** 
       
   172 	This structure defines the format for storing information for an 
       
   173 	individual message parameter. 
       
   174 	 
       
   175 	 iType - This defines the parameter type and is used by the CMessageParameterBase
       
   176 	 			class to instantiate the appropriate derived class via the 
       
   177 	 			KParameterFactoryFunctions factory lookup table.
       
   178 	 
       
   179 	 iMin, iMax - These are two constraints that are used in the ValidateL 
       
   180 	 			method of a class derived from CMessageParameter to validate the message
       
   181 	 			as required by that parameter.  
       
   182 	 			The  constraints that are used depend on the type as follows:
       
   183 	 			EParamInt:
       
   184 	 				-iMin = Minimum int value accepted
       
   185 	 				-iMax = Maximum int value accepted. This must be > iMin
       
   186 	 				
       
   187 	 				NOTE:	Currently unsigned integers are not explicitly supported,
       
   188 	 						however 16 bit unsigned integers are implicitly supported
       
   189 	 						by the EParamInt type.  Note that the constraint above
       
   190 	 						(iMax > iMin) means that the maximum supported value for an 
       
   191 	 						unsigned int is 0x7FFFFFFF.
       
   192 	 							 				
       
   193 	 			EParamDes8Read:
       
   194 	 			EParamDes16Read:
       
   195 	 				-iMin = Minimum length of descriptor in  clients address space.
       
   196 	 						If no minimum restriction exists this should be set to 0 in
       
   197 	 						the schema. This must be >= 0
       
   198 	 				-iMax = Maximum length of descriptor in clients address space.  
       
   199 	 						The descriptor supplied by the client must not have a 
       
   200 	 						length that exceeds this value. This must be >= iMin
       
   201 	 			EParamDes8:
       
   202 	 			EParamDes16:
       
   203 	 				-iMin =  Minimum MaxLength of descriptor in clients address space.
       
   204 	 						 The descriptor supplied by the client must have a MaxLength
       
   205 	 						 that is at least as big as this value. This must be >= 0
       
   206 	 				-iMax =  Maximum length of descriptor in clients address space.  
       
   207 	 						The descriptor supplied by the client must not have a 
       
   208 	 						length that exceeds this value. This must be >= 0.
       
   209 	 
       
   210 	 				NOTE: 	As the EParamDes* types use MaxLength() as a restriction
       
   211 	 						They cannot be used if the client intends to pass a TDesC 
       
   212 	 						derived descriptor.  If the client intends read only use 
       
   213 	 						then the explicit EParamDes*Read types should be used instead.
       
   214 	 						
       
   215 	 			EParamPckg:
       
   216 	 				-iMin = Minimum length of descriptor in  clients address space.
       
   217 	 						If no minimum restriction exists this should be set to 0 in
       
   218 	 						the schema. This must be >= 0
       
   219 	 				-iMax = Maximum length of descriptor in clients address space.  
       
   220 	 						The descriptor supplied by the client must not have a 
       
   221 	 						length that exceeds this value. This must be >= iMin
       
   222 	 
       
   223 	 			EParamPtr:
       
   224 	  				-iMin = Unused
       
   225 	 				-iMax = Unused
       
   226 	@publishedPartner
       
   227 	@released
       
   228 	*/
       
   229 	struct TParameterDetails
       
   230 		{
       
   231 		const TInt iType;
       
   232 		const TInt iMin;
       
   233 		const TInt iMax;	
       
   234 		};
       
   235 	
       
   236 	/**
       
   237 	This struct is used to represent a single message from the client.
       
   238 	It defines the function number corresponding to the message, the security 
       
   239 	policy for the message, the number of paramaters that are passed to the 
       
   240 	function and the type and constraint information for each of the parameters 
       
   241 	as described above. The server must define an array of these objects to be 
       
   242 	used by CClientMessage to validate all incoming messages.
       
   243 	
       
   244 	NOTE: It is assumed that the message parameters are contiguous. I.E. if there is one
       
   245 	parameter it is assumed to be located at index 0, if there are 2 parameters they 
       
   246 	are located at index 0,1 etc.
       
   247 	
       
   248 	@publishedPartner
       
   249 	@released
       
   250 	*/
       
   251 	struct TClientMessageSchema
       
   252 		{
       
   253 		
       
   254 		//Version number of the framework
       
   255 		const TInt iVersion;
       
   256 		
       
   257 		//The message number described by this schema
       
   258 		const TInt iFunction;
       
   259 		
       
   260 		//The security policy for this message. The CClientMessage framework 
       
   261 		//uses this security policy to police incoming messages.
       
   262 		const TStaticSecurityPolicy& iPolicy;
       
   263 		
       
   264 		//The number of parameters expected by this message
       
   265 		const TInt iParamCount;	
       
   266 		
       
   267 		//The array of TParameterDetails structs describing the 
       
   268 		//parameter types and constraints for this message
       
   269 		const TParameterDetails* iParams;
       
   270 		
       
   271 		//Reserved values for future proofing
       
   272 		const TInt iReserved1;
       
   273 		const TInt iReserved2;
       
   274 		};	
       
   275 	
       
   276 	/**
       
   277 	This struct is used to initialise the ClientMessage Framework.
       
   278 	This struct provides the framework with the message schema and
       
   279 	the custom validation functions for the server as well as the server 
       
   280 	name and flags.
       
   281 	The struct should be populated by the server using the SERVER_DATA 
       
   282 	macro defined below.
       
   283 	@publishedPartner
       
   284 	@released
       
   285 	*/
       
   286 	struct TClientMessageServerData
       
   287 		{
       
   288 		//Version number of this structure
       
   289 		const TInt iVersion;
       
   290 		
       
   291 		//The number of messages accepted by this server
       
   292 		const TInt iMessageCount;
       
   293 		
       
   294 		//The array of TClientMessageSchema structs defining the schema for
       
   295 		//each message accpeted by this server
       
   296 		const TClientMessageSchema* iMessageSchema;
       
   297 		
       
   298 		//The number of custom validation fucntions suplpied by this server
       
   299 		const TInt iValidationFnCount;
       
   300 		
       
   301 		//The array of custom validation functions supplied by this server.
       
   302 		//These validation functions are called from ValidateL to provide 
       
   303 		//customised validation of any parameter type.
       
   304 		const TCustomValidationFn* iCustomValidationFns;
       
   305 		
       
   306 		//The name of the server using the framework.  This string is used both
       
   307 		//in logging bad messages and in panicing the client or the server.
       
   308 		//In line with Panic category strings, this value should be 16 characters or less.
       
   309 		const TUint8* iServerName;
       
   310 		
       
   311 		//Flags used to pass settings info into the framework. The supported values are
       
   312 		//defined in the TServerFlags enum above. 
       
   313 		const TInt iFlags;
       
   314 		
       
   315 		//Reserved values for future proofing
       
   316 		const TInt iReserved1;
       
   317 		const TInt iReserved2;
       
   318 		};
       
   319 	
       
   320 	//Macro Definitions
       
   321 	
       
   322 	/**
       
   323 	This macro is used to simplify declaration of TClientMessageSchema entries.
       
   324 	The function number, security policy and pointer to array of TParameterDetails
       
   325 	structures is converted into the expected format for the declaration of a
       
   326 	TClientMessageSchema structure.
       
   327 	@publishedPartner
       
   328 	@released
       
   329 	*/	
       
   330 	#define MESSAGE_SCHEMA(Function,Policy,Params) {KClientMessageVersion,Function,Policy,sizeof(Params)/sizeof(TParameterDetails),Params,0,0}
       
   331 
       
   332 	
       
   333 	/**
       
   334 	This TParameterDetails structure is used to represent a message with no 
       
   335 	parameters.  This is required as the schema expects a const TParameterDetails*.
       
   336 	@publishedPartner
       
   337 	@released
       
   338 	*/
       
   339 	const TParameterDetails KNoParams[1] = {{EParamNull,0,0}};	
       
   340 		
       
   341 	/**
       
   342 	This macro is used to simplify declaration of TClientMessageSchema entries
       
   343 	for functions with no parameters. Because the number of parameters is set 
       
   344 	to 0, a CMessageParameterBase derived object is not instantiated for this 
       
   345 	parameter type.
       
   346 	@publishedPartner
       
   347 	@released
       
   348 	*/
       
   349 	#define MESSAGE_SCHEMA_NO_PARAMS(Function,Policy) {KClientMessageVersion,Function,Policy,0,KNoParams,0,0}
       
   350 		
       
   351 	
       
   352 	/**
       
   353 	This macro is used to simplify declaration of the TClientMessageServerData structure.
       
   354 	The pointer to the array of TClientMessageSchemas, pointer to array of 
       
   355 	TCustomValidationFns, server name and server flags are converted into the 
       
   356 	expected format for the declaration of a TClientMessageServerData structure.
       
   357 	@publishedPartner
       
   358 	@released
       
   359 	*/	
       
   360 	#define SERVER_DATA(ClientMessages,ValidationFns,ServerName,Flags){KClientMessageVersion,sizeof(ClientMessages)/sizeof(TClientMessageSchema),ClientMessages,sizeof(ValidationFns)/sizeof(TCustomValidationFn),ValidationFns,(TUint8*)ServerName,Flags,0,0}
       
   361 	
       
   362 		
       
   363 	//Class Declarations
       
   364 	
       
   365 	/**
       
   366 	This is the abstract base class for all message parameter classes. 
       
   367 	The class defines one pure virtual function, ValidateL, which all derived classes 
       
   368 	must implement.  This class also defines default implementation for the access
       
   369 	methods which should be properly defined in all derived classes.
       
   370 	This class is not intended for external derivation.
       
   371 	@publishedPartner
       
   372 	@released
       
   373 	*/
       
   374 	NONSHARABLE_CLASS(CMessageParameterBase) : public CBase
       
   375 	{
       
   376 	public:
       
   377 		static CMessageParameterBase* CreateL(const TParameterDetails& aParam, TInt aParamIndex,
       
   378 							const RMessage2& aMessage);
       
   379 		virtual void ValidateL() = 0;
       
   380 		virtual ~CMessageParameterBase(){};
       
   381 		
       
   382 		virtual TInt GetIntL();
       
   383 		virtual const TAny* GetPtrL();
       
   384 		virtual const TDesC8& GetDes8L();
       
   385 		virtual const TDesC& GetDes16L();
       
   386 		virtual TInt GetDesLengthL();
       
   387 		virtual TInt GetDesMaxLengthL();
       
   388 		virtual void ReadL(TDes8& aDes, TInt aOffset);
       
   389 		virtual void ReadL(TDes& aDes, TInt aOffset);
       
   390 		virtual void WriteL(const TDesC8& aDes, TInt aOffset);
       
   391 		virtual void WriteL(const TDesC& aDes, TInt aOffset);
       
   392 		
       
   393 		virtual TInt Min();
       
   394 		virtual TInt Max();
       
   395 		
       
   396 	protected:
       
   397 		CMessageParameterBase(const TParameterDetails& aParam, TInt aParamIndex,
       
   398 					const RMessage2& aMessage, TCustomValidationFn aValidationFn);
       
   399 		
       
   400 	private:
       
   401 	static TCustomValidationFn GetValidationFunctionL(const TParameterDetails& aParam);
       
   402 	
       
   403 	protected:	
       
   404 		//The index of this parameter within the corresponding RMessage2 object
       
   405 		TInt iIndex;
       
   406 		
       
   407 		//A reference to the RMessage2 object that contains this parameter
       
   408 		const RMessage2& iMessage;
       
   409 		
       
   410 		//A reference to the structure that defines the expected type
       
   411 		//and constraints for this parameter
       
   412 		const TParameterDetails& iParamDetails; 
       
   413 		
       
   414 		//A custom validation function to allow user defined validation
       
   415 		//this function is called from ValidateL
       
   416 		TCustomValidationFn iValidationFn;
       
   417 		
       
   418 	};
       
   419 
       
   420 	/**
       
   421 	This class is used by a server to sanitise incoming messages.  
       
   422 	The class provides a wrapper around an RMessage2 object and provides a method 
       
   423 	for validation of the message against the constraints defined in the message schema.  
       
   424 	This class also provides methods for safely accessing the message arguments, 
       
   425 	and for error handling and logging of bad messages.
       
   426 	This class is not intended for derivation.
       
   427 	@publishedPartner
       
   428 	@released
       
   429 	*/
       
   430 	NONSHARABLE_CLASS(CClientMessage) : public CBase
       
   431 	{
       
   432 	public:
       
   433 		IMPORT_C static void InitialiseFrameworkL(const TClientMessageServerData& aServerData);
       
   434 		IMPORT_C static CClientMessage* NewL(const RMessage2& aMessage);
       
   435 		IMPORT_C virtual ~CClientMessage();
       
   436 		
       
   437 		IMPORT_C TInt Function();
       
   438 		IMPORT_C const RMessage2& Message();
       
   439 		IMPORT_C virtual void ValidateL();
       
   440 		IMPORT_C virtual void ValidateL(TInt aParam);
       
   441 		IMPORT_C virtual void CompleteRequestL(TInt aError);
       
   442 		IMPORT_C virtual void PanicClient(const TDesC& aServer, TInt aPanic);
       
   443 		
       
   444 		IMPORT_C virtual TInt GetIntL(TInt aParam);		
       
   445 		IMPORT_C virtual const TAny* GetPtrL(TInt aParam);		
       
   446 		IMPORT_C virtual const TDesC8& GetDes8L(TInt aParam);
       
   447 		IMPORT_C virtual const TDesC& GetDes16L(TInt aParam);
       
   448 		IMPORT_C virtual TInt GetDesLengthL(TInt aParam);
       
   449 		IMPORT_C virtual TInt GetDesMaxLengthL(TInt aParam);	
       
   450 		IMPORT_C virtual void ReadL(TInt aParam, TDes8& aDes, TInt aOffset = 0);
       
   451 		IMPORT_C virtual void ReadL(TInt aParam, TDes16& aDes, TInt aOffset = 0);
       
   452 		IMPORT_C virtual void WriteL(TInt aParam, const TDesC8& aDes, TInt aOffset = 0);
       
   453 		IMPORT_C virtual void WriteL(TInt aParam, const TDesC16& aDes, TInt aOffset = 0);		
       
   454 	
       
   455 	private:
       
   456 		virtual void LogBadMessageL(TInt aError);
       
   457 		virtual void CheckSecurityPolicyL(const TSecurityPolicy& aPolicy);	
       
   458 		CClientMessage(const RMessage2& aMessage,const TClientMessageServerData& aServerData);
       
   459 		void ConstructL();
       
   460 		const TClientMessageSchema* FindMessageSchema();
       
   461 		void CheckValidatedL(TInt aParam);
       
   462 		TBool LogBadMessages();
       
   463 		
       
   464 	private:
       
   465 		//Array of pointers to CMessageParameterBase Derived parameter objects used
       
   466 		// to validate and access the individual message arguments
       
   467 		RPointerArray <CMessageParameterBase> iParameters;
       
   468 		
       
   469 		//Reference to the underlying RMessage2 wrapped by this object
       
   470 		const RMessage2& iMessage;
       
   471 		
       
   472 		//Reference to TClientMessageServerData structure stored in TLS for
       
   473 		//this thread.  This structure is passed in to the framework by the server
       
   474 		//on initialisation.
       
   475 		const TClientMessageServerData& iServerData;
       
   476 		
       
   477 		//Bit flags for use internally within CClientMessage.
       
   478 		TBitFlags32 iFlags;
       
   479 	};
       
   480 	/**
       
   481 	This class is used for Base64 based encoding and decoding .
       
   482 	This class provides a method  for encoding and decoding
       
   483 	@publishedPartner
       
   484 	@released
       
   485 	*/
       
   486 	class Base64Codec 
       
   487 	{
       
   488 		// base64 and UU coding defines.
       
   489 		/**
       
   490 		This is the list of Bitmask used for encoding and decoding
       
   491 		@publishedPartner
       
   492 		@released
       
   493 		*/
       
   494 		enum EMaskValues
       
   495 			{ 
       
   496 			ESixBitMask = 0x3F, 
       
   497 			EEightBitMask = 0xFF 
       
   498 			};
       
   499 		
       
   500 		/**
       
   501 		This is the list of shift values used for encoding and decoding
       
   502 		@publishedPartner
       
   503 		@released
       
   504 		*/
       
   505 		enum EMaskShiftValues
       
   506 			{ 
       
   507 			ESix = 6, 
       
   508 			EFour = 4, 
       
   509 			ETwo = 2, 
       
   510 			EZero = 0
       
   511 			};
       
   512 		
       
   513 		/**
       
   514 		This enum is used as padding charcter
       
   515 		@publishedPartner
       
   516 		@released
       
   517 		*/
       
   518 		enum
       
   519 		{ 
       
   520 		EPadChar = 64 
       
   521 		};
       
   522 	public:
       
   523 		IMPORT_C static TInt Encode(const TDesC8& aSrcString, TDes8& aDestString);
       
   524 		IMPORT_C static TInt Decode(const TDesC8& aSrcString, TDes8& aDestString);
       
   525 	};
       
   526 	}//namespace
       
   527 
       
   528 #endif