debugsrv/runmodedebug/securityserver/src/c_security_svr_server.cpp
branchRCL_3
changeset 21 52e343bb8f80
parent 20 ca8a1b6995f6
child 22 e26895079d7c
equal deleted inserted replaced
20:ca8a1b6995f6 21:52e343bb8f80
     1 // Copyright (c) 2006-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 the License "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 // Provides the debug security server server implementation.
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalTechnology
       
    21  @released
       
    22 */
       
    23 
       
    24 #include <e32base.h>
       
    25 #include <e32base_private.h>
       
    26 #include <rm_debug_api.h>
       
    27 #include "c_process_pair.h"
       
    28 #include "c_security_svr_session.h"
       
    29 #include "c_security_svr_server.h"
       
    30 #include "rm_debug_logging.h"
       
    31 
       
    32 using namespace Debug;
       
    33 
       
    34 /**
       
    35 Server constructor, sessions are created as ESharableSessions, meaning that
       
    36 each session will be used by at most one debug agent
       
    37 */
       
    38 CSecuritySvrServer::CSecuritySvrServer(CActive::TPriority aActiveObjectPriority)
       
    39 	: CServer2(aActiveObjectPriority, ESharableSessions),
       
    40 	  iSessionCount(0),
       
    41 	  iShutdown()
       
    42 	{
       
    43 	LOG_MSG("CSecuritySvrServer::CSecuritySvrServer()\n");
       
    44 	}
       
    45 
       
    46 /**
       
    47 Standard implementation
       
    48 
       
    49 @return pointer to new CSecuritySvrServer object
       
    50 */
       
    51 CSecuritySvrServer* CSecuritySvrServer::NewLC()
       
    52 	{
       
    53 	LOG_MSG("CSecuritySvrServer::NewLC()\n");
       
    54 
       
    55 	CSecuritySvrServer* self=new(ELeave) CSecuritySvrServer(EPriorityStandard);
       
    56 	CleanupStack::PushL(self);
       
    57 	self->ConstructL();
       
    58 	return self;
       
    59 	}
       
    60 
       
    61 /**
       
    62 Server destructor, performs cleanup for the server
       
    63 */
       
    64 CSecuritySvrServer::~CSecuritySvrServer()
       
    65 	{
       
    66 	LOG_MSG("CSecuritySvrServer::~CSecuritySvrServer()\n");
       
    67 
       
    68 	// stop the kernel side driver
       
    69 	iKernelDriver.Close();
       
    70 	User::FreeLogicalDevice(KDebugDriverName);
       
    71 
       
    72 	//deallocate both the debug maps
       
    73 	iPassiveDebugMap.ResetAndDestroy();
       
    74 	iActiveDebugMap.ResetAndDestroy();
       
    75 	}
       
    76 
       
    77 /**
       
    78 Starts the server and constructs and starts the servers shutdown timer
       
    79 */
       
    80 void CSecuritySvrServer::ConstructL()
       
    81 	{
       
    82 	LOG_MSG("CSecuritySvrServer::ConstructL()");
       
    83 
       
    84 	StartL(KSecurityServerName);
       
    85 	iShutdown.ConstructL();
       
    86 	iShutdown.Start();
       
    87 
       
    88 	//load the kernel driver
       
    89 	TInt err = User::LoadLogicalDevice(KDebugDriverFileName);
       
    90 	if(! ((KErrNone == err) || (KErrAlreadyExists == err)))
       
    91 		{
       
    92 		User::Leave(err);
       
    93 		}
       
    94 	//create an information object for initialising the driver
       
    95 	TRM_DebugDriverInfo driverInfo;
       
    96 	driverInfo.iUserLibraryEnd = 0;
       
    97 	User::LeaveIfError(iKernelDriver.Open(driverInfo));
       
    98 	}
       
    99 
       
   100 /**
       
   101 Creates a new session with the DSS. A version check is done to ensure that an
       
   102 up to date version of the DSS is available (according to the DA's needs).
       
   103 The device driver is loaded if necessary and a session with the server and a 
       
   104 handle to the driver opened.
       
   105 
       
   106 @param aRequiredVersion the minimal version of the DSS required by the DA
       
   107 
       
   108 @return a pointer to the new sever session, or NULL if any of the 
       
   109         initialisation process failed
       
   110 */
       
   111 CSession2* CSecuritySvrServer::NewSessionL(const TVersion& aRequiredVersion, const RMessage2& aMessage) const
       
   112 //
       
   113 // Session constructor
       
   114 //
       
   115 	{
       
   116 	LOG_ARGS("version=%d.%d.%d", aRequiredVersion.iMajor, aRequiredVersion.iMinor, aRequiredVersion.iBuild);
       
   117 
       
   118 	//assert compatible version
       
   119 	TVersion currentVersion(KDebugServMajorVersionNumber, KDebugServMinorVersionNumber, KDebugServPatchVersionNumber);
       
   120 	if(!User::QueryVersionSupported(currentVersion, aRequiredVersion))
       
   121 		{
       
   122 		LOG_MSG("Requested version not compatible with this version. Asked for %d.%d.%d but this is %d.%d.%d", aRequiredVersion.iMajor, aRequiredVersion.iMinor, aRequiredVersion.iBuild, KDebugServMajorVersionNumber, KDebugServMinorVersionNumber, KDebugServPatchVersionNumber);
       
   123 		User::Leave(KErrNotSupported);
       
   124 		}
       
   125 	
       
   126 	//get the debug agent's process id
       
   127 	RThread clientThread;
       
   128 	User::LeaveIfError(aMessage.Client(clientThread));
       
   129 	CleanupClosePushL(clientThread);
       
   130 	RProcess clientProcess;
       
   131 	User::LeaveIfError(clientThread.Process(clientProcess));
       
   132 	CleanupStack::PopAndDestroy(&clientThread);
       
   133 	TProcessId processId = clientProcess.Id();
       
   134 	clientProcess.Close();
       
   135 
       
   136 	//create session
       
   137 	LOG_MSG("About to call new(ELeave) CSecuritySvrSession()");
       
   138 	CSecuritySvrSession* servSession = new(ELeave) CSecuritySvrSession(processId);
       
   139 
       
   140 	CleanupStack::PushL(servSession);
       
   141 	servSession->ConstructL();
       
   142 	CleanupStack::Pop(servSession);
       
   143 	return servSession;
       
   144 	}
       
   145 
       
   146 /**
       
   147 Manages requests from debug agents to attach to target debug processes
       
   148 
       
   149 Given the debug agent process ID and the target process name:
       
   150 (1) checks whether the pair is already in either of the debug maps, if so
       
   151     then returns KErrAlreadyExists
       
   152 (2) if aPassive == ETrue then just add the pair to the passive map and return
       
   153     whatever the return value of the array write was
       
   154 (3) if aPassive == EFalse then check whether the target debug process is 
       
   155     already reserved by another debug agent. If it is then return KErrInUse,
       
   156     otherwise add the pair to the active debug map and return the status 
       
   157     value of the array write.
       
   158 
       
   159 @param aTargetProcessName original FileName of the process to attach to
       
   160 @param aDebugAgentProcessId process ID of the debug agent
       
   161 @param aPassive ETrue if wish to attach passively, EFalse otherwise
       
   162 
       
   163 @return KErrNone if successfully attached, otherwise another system wide error
       
   164         code as above
       
   165 */
       
   166 TInt CSecuritySvrServer::AttachProcessL(const TDesC& aTargetProcessName, const TProcessId aDebugAgentProcessId, const TBool aPassive)
       
   167 	{
       
   168 	//store the pair of values
       
   169 	LOG_MSG3("CSecuritySvrServer::AttachProcessL() 0x%lx aPassive=%d", aDebugAgentProcessId.Id(), aPassive);
       
   170 
       
   171 	CProcessPair *processPair = CProcessPair::NewL(aTargetProcessName, aDebugAgentProcessId);
       
   172 	if(processPair == NULL)
       
   173 		return KErrNoMemory;
       
   174 
       
   175 	//check whether the pair already exists in the active debug map
       
   176 	for(TInt i=0; i<iActiveDebugMap.Count(); i++)
       
   177 		{
       
   178         // Note that the equality is of the debug agent id and the proc name
       
   179 		if(*processPair == *(iActiveDebugMap[i]))
       
   180 			{
       
   181 			//process already exists
       
   182 			LOG_MSG( "  AttachProcessL() error : KErrAlreadyExists in active map\n" );
       
   183 			delete processPair;
       
   184 			return KErrAlreadyExists;
       
   185 			}
       
   186 		}
       
   187 
       
   188 	//check whether the pair already exists in the passive map
       
   189 	for(TInt i=0; i<iPassiveDebugMap.Count(); i++)
       
   190 		{
       
   191 		if(*processPair == *(iPassiveDebugMap[i]))
       
   192 			{
       
   193 			//process already exists
       
   194 			LOG_MSG( "  AttachProcessL() error : KErrAlreadyExists in passive map\n" );
       
   195 			delete processPair;
       
   196 			return KErrAlreadyExists;
       
   197 			}
       
   198 		}
       
   199 
       
   200 	if(aPassive)
       
   201 		{
       
   202 		//just add the pair and return
       
   203 		TInt err = iPassiveDebugMap.Append(processPair);
       
   204 		if(err != KErrNone)
       
   205 			{
       
   206 			// couldn't add pair for some unknown reason, so delete the pair
       
   207 			LOG_MSG2( "  AttachProcessL() error %d appending passive process pair", err );
       
   208 			delete processPair;
       
   209 			}
       
   210 		return err;
       
   211 		}
       
   212 	else
       
   213 		{
       
   214 		//check whether the process Id has already been reserved
       
   215 		for(TInt i=0; i<iActiveDebugMap.Count(); i++)
       
   216 			{
       
   217             // Now check if this is already debugged, but only if its for a particular process.
       
   218             // We can have several entries from AttachAll calls, and its ok to add them
       
   219 			if( (!processPair->ProcessNameMatches(_L("*"))) &&
       
   220 			    (processPair->ProcessNameMatches(*(iActiveDebugMap[i])) ) )
       
   221 				{
       
   222 				//process already being debugged
       
   223 				LOG_MSG( "  AttachProcessL() error : process already being debugged" );
       
   224 				delete processPair;
       
   225 				return KErrInUse;
       
   226 				}
       
   227 			}
       
   228 		//try to add the pair. 
       
   229 		TInt err = iActiveDebugMap.Append(processPair);
       
   230 		if(err != KErrNone)
       
   231 			{
       
   232 			// couldn't add pair for some unknown reason, so delete the pair
       
   233 			LOG_MSG2( "  AttachProcessL() error %d inserting active process pair", err );
       
   234 			delete processPair;
       
   235 			}
       
   236 		return err;
       
   237 		}
       
   238 	}
       
   239 
       
   240 /*
       
   241 Detach from debugging the specified process
       
   242 
       
   243 @param aTargetProcessName name of the process to detach from
       
   244 @param aDebugAgentProcessId process ID of the debug agent
       
   245 
       
   246 @return KErrNone if successfully detached, KErrNotFound if an attempt is made
       
   247         to detach from a process which the debug agent hasn't previously attached to
       
   248 */
       
   249 TInt CSecuritySvrServer::DetachProcess(const TDesC& aTargetProcessName, const TProcessId aDebugAgentProcessId)
       
   250 	{
       
   251     LOG_MSG2( "CSecuritySvrServer::DetachProcess() for agent with id 0x%lx", aDebugAgentProcessId.Id() );
       
   252 
       
   253 	//check whether the pair is in the active debug map
       
   254 	for(TInt i=0; i<iActiveDebugMap.Count(); i++)
       
   255 		{
       
   256 		if(iActiveDebugMap[i]->Equals(aTargetProcessName, aDebugAgentProcessId))
       
   257 			{
       
   258 			//remove the process pair from the active debug map
       
   259 			delete iActiveDebugMap[i];
       
   260 			iActiveDebugMap.Remove(i);
       
   261 			return KErrNone;
       
   262 			}
       
   263 		}
       
   264 
       
   265 	//check whether the pair is in the passive debug map
       
   266 	for(TInt i=0; i<iPassiveDebugMap.Count(); i++)
       
   267 		{
       
   268 		if(iPassiveDebugMap[i]->Equals(aTargetProcessName, aDebugAgentProcessId))
       
   269 			{
       
   270 			//remove the process pair from the active debug map
       
   271 			delete iPassiveDebugMap[i];
       
   272 			iPassiveDebugMap.Remove(i);
       
   273 			return KErrNone;
       
   274 			}
       
   275 		}
       
   276 
       
   277 	//process pair wasn't in either map
       
   278 	return KErrNotFound;
       
   279 	}
       
   280 
       
   281 /**
       
   282 Given a debug agent process ID, removes all references to that debug agent
       
   283 from the debug maps
       
   284 
       
   285 @param aMessage message from the debug agent
       
   286 
       
   287 @return returns KErrNone if successful, another system wide error code otherwise
       
   288 */
       
   289 void CSecuritySvrServer::DetachAllProcesses(const TProcessId aDebugAgentProcessId)
       
   290 	{
       
   291 	//check whether the debug agent process ID is in the active debug map
       
   292 	for(TInt i=iActiveDebugMap.Count()-1; i>=0; i--)
       
   293 		{
       
   294 		if(iActiveDebugMap[i]->ProcessIdMatches(aDebugAgentProcessId))
       
   295 			{
       
   296 			//remove the process pair from the active debug map
       
   297 			delete iActiveDebugMap[i];
       
   298 			iActiveDebugMap.Remove(i);
       
   299 			}
       
   300 		}
       
   301 
       
   302 	//check whether the debug agent process ID is in the passive debug map
       
   303 	for(TInt i=iPassiveDebugMap.Count()-1; i>=0; i--)
       
   304 		{
       
   305 		if(iPassiveDebugMap[i]->ProcessIdMatches(aDebugAgentProcessId))
       
   306 			{
       
   307 			//remove the process pair from the passive debug map
       
   308 			delete iPassiveDebugMap[i];
       
   309 			iPassiveDebugMap.Remove(i);
       
   310 			}
       
   311 		}
       
   312 	}
       
   313 
       
   314 /*
       
   315 Check whether the specified debug agent is attaced to the specfied target
       
   316 process.
       
   317 
       
   318 @param aTargetThreadId thread ID of a thread in the target process
       
   319 @param aMessage a message which originates with the debug agent
       
   320 @param aPassive if EFalse then checks whether the debug agent is the active
       
   321        debugger of the target process. If ETrue then checks whether the debug
       
   322        agent is attached to the target process, irrespective of whether it is
       
   323        attached passively or actively
       
   324 
       
   325 @return ETrue if attached, EFalse otherwise
       
   326 */
       
   327 TBool CSecuritySvrServer::CheckAttached(const TThreadId aTargetThreadId, const RMessage2& aMessage, const TBool aPassive)
       
   328 	{
       
   329 	
       
   330 	//get a handle to the target thread
       
   331 	RThread targetThread;
       
   332 	TInt err = targetThread.Open(aTargetThreadId);
       
   333 	if(err != KErrNone)
       
   334 		{
       
   335 		return EFalse;
       
   336 		}
       
   337 
       
   338 	//get a handle to the target process
       
   339 	RProcess targetProcess;
       
   340 	err = targetThread.Process(targetProcess);
       
   341 	//finshed with the thread handle so close it
       
   342 	targetThread.Close();
       
   343 	if(err != KErrNone)
       
   344 		return EFalse;
       
   345 
       
   346 	//get the target process' file name
       
   347 	TFileName targetFileName = targetProcess.FileName();
       
   348 
       
   349 	// Tamperproofing. Ensure that the debug agent really has a superset
       
   350 	// of the target process PlatSec capabilities, as authorised
       
   351 	// by an OEM Debug Token (if any)
       
   352 
       
   353 	TSecurityInfo targetSecInfo(targetProcess);
       
   354 
       
   355 	// Now compare the capabilities, to ensure the DebugAgent has been authorised with
       
   356 	// sufficient capabilities from its OEM Debug token
       
   357 	CSecuritySvrSession* session = (CSecuritySvrSession*)aMessage.Session();
       
   358 
       
   359 	// Presume we need to check the target process is debuggable unless a valid OEM Debug token in effect?
       
   360 	if (!OEMTokenPermitsDebugL(session->GetOEMDebugCapabilities(), targetSecInfo.iCaps) )
       
   361 		{
       
   362 		// No debug token therefore check if the process is debuggable
       
   363 		err = iKernelDriver.IsDebuggable(targetProcess.Id());
       
   364 		}
       
   365 
       
   366 	//finished with the process handle so close it
       
   367 	targetProcess.Close();
       
   368 
       
   369 	if (err != KErrNone)
       
   370 	{
       
   371 		// The process was not marked as debuggable by the loader, and the OEM
       
   372 		// debug token did not override the lack of a debuggable bit.
       
   373 		// The process was not marked as debuggable by the loader
       
   374 		return EFalse;
       
   375 	}
       
   376 
       
   377 	return CheckAttachedProcess(targetFileName, aMessage, aPassive);
       
   378 	}
       
   379 
       
   380 /*
       
   381 Check whether the specified debug agent is attaced to the specfied target
       
   382 process.
       
   383 
       
   384 @param aTargetProcessId process ID of the target process
       
   385 @param aMessage a message which originates with the debug agent
       
   386 @param aPassive if EFalse then checks whether the debug agent is the active
       
   387        debugger of the target process. If ETrue then checks whether the debug
       
   388        agent is attached to the target process, irrespective of whether it is
       
   389        attached passively or actively
       
   390 
       
   391 @return ETrue if attached, EFalse otherwise
       
   392 */
       
   393 TBool CSecuritySvrServer::CheckAttached(const TProcessId aTargetProcessId, const RMessage2& aMessage, const TBool aPassive)
       
   394 	{
       
   395 	//get a handle to the target process
       
   396 	RProcess targetProcess;
       
   397 	TInt err =targetProcess.Open(aTargetProcessId);
       
   398 	if(err != KErrNone)
       
   399 		{
       
   400 		return EFalse;
       
   401 		}
       
   402 
       
   403 	//get the target process' file name
       
   404 	TFileName targetFileName = targetProcess.FileName();
       
   405 
       
   406 	// Tamperproofing. Ensure that the debug agent really has a superset
       
   407 	// of the target process PlatSec capabilities, as authorised
       
   408 	// by an OEM Debug Token (if any)
       
   409 
       
   410 	TSecurityInfo targetSecInfo(targetProcess);
       
   411 
       
   412 	// Now compare the capabilities, to ensure the DebugAgent has been authorised with
       
   413 	// sufficient capabilities from its OEM Debug token
       
   414 	CSecuritySvrSession* session = (CSecuritySvrSession*)aMessage.Session();
       
   415 
       
   416 	// Presume we need to check the target process is debuggable unless a valid OEM Debug token in effect?
       
   417 	if ( !OEMTokenPermitsDebugL(session->GetOEMDebugCapabilities(), targetSecInfo.iCaps) )
       
   418 		{
       
   419 		// No debug token therefore check if the process is debuggable
       
   420 		err = iKernelDriver.IsDebuggable(targetProcess.Id());
       
   421 		}
       
   422 
       
   423 	//finished with the process handle so close it
       
   424 	targetProcess.Close();
       
   425 
       
   426 	if (err != KErrNone)
       
   427 	{
       
   428 		return EFalse;
       
   429 	}
       
   430 
       
   431 	return CheckAttachedProcess(targetFileName, aMessage, aPassive);
       
   432 	}
       
   433 
       
   434 /*
       
   435 Check whether the specified debug agent is attaced to the specfied target
       
   436 process.
       
   437 
       
   438 @param aTargetProcessName 
       
   439 @param aMessage a message which originates with the debug agent
       
   440 
       
   441 @return ETrue if attached, EFalse otherwise
       
   442 */
       
   443 TBool CSecuritySvrServer::CheckAttachedProcess(const TDesC& aTargetProcessName, const RMessage2& aMessage, const TBool aPassive) const
       
   444 	{
       
   445 	//get the debug agent's process id
       
   446 	TProcessId clientProcessId = 0;
       
   447 	TInt err = GetProcessIdFromMessage(clientProcessId, aMessage);
       
   448 	if(err != KErrNone)
       
   449 		return EFalse;
       
   450 
       
   451 	//check permissions
       
   452 	if(aPassive)
       
   453 		return IsDebugger(aTargetProcessName, clientProcessId);
       
   454 	else
       
   455 		return IsActiveDebugger(aTargetProcessName, clientProcessId);
       
   456 	}
       
   457 
       
   458 /**
       
   459 Tests whether the debug agent is attached actively to the target debug process
       
   460 
       
   461 @param aTargetProcessName target debug process' FileName
       
   462 @param aDebugAgentProcessId process ID of a debug agent
       
   463 
       
   464 @return ETrue if the specified debug agent is actively attached to the 
       
   465         specified target debug process, EFalse otherwise
       
   466 */
       
   467 TBool CSecuritySvrServer::IsActiveDebugger(const TDesC& aTargetProcessName, const TProcessId aDebugAgentProcessId) const
       
   468 	{
       
   469 	//check whether the pair is in the active debug map
       
   470 	for(TInt i=0; i<iActiveDebugMap.Count(); i++)
       
   471 		{
       
   472 		// If both match, which can include aTargetProcessName being "*"
       
   473 		if(iActiveDebugMap[i]->Equals(aTargetProcessName, aDebugAgentProcessId))
       
   474 			{
       
   475 			LOG_MSG2( "CSecuritySvrServer::IsActiveDebugger() for agent id 0x%lx matches name and pid", 
       
   476 					aDebugAgentProcessId.Id() );			
       
   477 			return ETrue;
       
   478 			}
       
   479 		// if the pid matches and the name in the map is "*", indicating that 
       
   480 		// this is an attach all agent, and thus debugging 
       
   481 		if( iActiveDebugMap[i]->ProcessIdMatches(aDebugAgentProcessId) &&
       
   482 			iActiveDebugMap[i]->ProcessNameMatches(_L("*")) )
       
   483 			{
       
   484 			LOG_MSG2( "CSecuritySvrServer::IsActiveDebugger() for AttachAll agent id 0x%lx", 
       
   485 				aDebugAgentProcessId.Id() );
       
   486 			return ETrue;
       
   487 			}
       
   488 		}
       
   489 	//not found so return false
       
   490 	return EFalse;
       
   491 	}
       
   492 
       
   493 /**
       
   494 Tests whether the target process is being debugged
       
   495 
       
   496 @param aTargetProcessName target process' FileName
       
   497 @param aPassive indicates whether to check for the process being actively debugged,
       
   498 or passively debugged
       
   499 
       
   500 @return ETrue if the specified target process is being debugged,
       
   501         EFalse otherwise
       
   502 */
       
   503 TBool CSecuritySvrServer::IsDebugged(const TDesC& aTargetProcessName, const TBool aPassive) const
       
   504 	{
       
   505 	//get a reference to the appropriate list
       
   506 	const RPointerArray<CProcessPair>& map = (aPassive) ? iPassiveDebugMap : iActiveDebugMap;
       
   507 
       
   508 	//iterate through the map trying to match the aTargetProcessName
       
   509 	for(TInt i=0; i<map.Count(); i++)
       
   510 		{
       
   511 		if(map[i]->ProcessNameMatches(aTargetProcessName))
       
   512 			{
       
   513 			return ETrue;
       
   514 			}
       
   515 		}
       
   516 	return EFalse;
       
   517 	}
       
   518 
       
   519 /**
       
   520 Tests whether the debug agent is attached to the target debug process
       
   521 
       
   522 @param aTargetProcessName target debug process' FileName
       
   523 @param aDebugAgentProcessId process ID of a debug agent
       
   524 
       
   525 @return ETrue if the specified debug agent is attached to the 
       
   526         specified target debug process (regardless of whether it is attached
       
   527 	passively or actively), EFalse otherwise
       
   528 */
       
   529 TBool CSecuritySvrServer::IsDebugger(const TDesC& aTargetProcessName, const TProcessId aDebugAgentProcessId) const
       
   530 	{
       
   531 	//check whether the pair is in the active debug map
       
   532 	if(IsActiveDebugger(aTargetProcessName, aDebugAgentProcessId))
       
   533 		return ETrue; 
       
   534 
       
   535 	//check whether the pair is in the passive debug map
       
   536 	for(TInt i=0; i<iPassiveDebugMap.Count(); i++)
       
   537 		{
       
   538 		if(iPassiveDebugMap[i]->Equals(aTargetProcessName, aDebugAgentProcessId))
       
   539 			return ETrue;
       
   540 		}
       
   541 	//not found so return false
       
   542 	return EFalse;
       
   543 	}
       
   544 
       
   545 /**
       
   546 Decrements the server's count of how many sessions are connected to it and
       
   547 starts the shutdown timer if there are no sessions connected
       
   548 */
       
   549 void CSecuritySvrServer::SessionClosed()
       
   550 	{
       
   551 	if(--iSessionCount < 1)
       
   552 		{
       
   553 		iShutdown.Start();
       
   554 		}
       
   555 	}
       
   556 
       
   557 /**
       
   558 Increments the servers count of how many sessions are connected to it and
       
   559 cancels the shutdown timer if it is running
       
   560 */
       
   561 void CSecuritySvrServer::SessionOpened()
       
   562 	{
       
   563 	iSessionCount++;
       
   564 	iShutdown.Cancel();
       
   565 	}
       
   566 
       
   567 /** 
       
   568   Get the process id of the thread which sent aMessage
       
   569   @param aProcessId process id of the thread which sent aMessage
       
   570   @param aMessage message object sent by thread 
       
   571 
       
   572   @return KErrNone if aProcessId could be set, or one of the system wide error codes if not
       
   573   */
       
   574 TInt CSecuritySvrServer::GetProcessIdFromMessage(TProcessId& aProcessId, const RMessage2& aMessage) const
       
   575 	{
       
   576 	//get the debug agent's thread
       
   577 	RThread clientThread;
       
   578 	TInt err = aMessage.Client(clientThread);
       
   579 	if(err != KErrNone)
       
   580 		{
       
   581 		return err;
       
   582 		}
       
   583 
       
   584 	//get the debug agent's process
       
   585 	RProcess clientProcess;
       
   586 	err = clientThread.Process(clientProcess);
       
   587 
       
   588 	//finished with the thread handle so close it
       
   589 	clientThread.Close();
       
   590 
       
   591 	//check if there was an error from getting the process
       
   592 	if(err != KErrNone)
       
   593 		{
       
   594 		return err;
       
   595 		}
       
   596 
       
   597 	//get the debug agent's process id
       
   598 	aProcessId = clientProcess.Id();
       
   599 
       
   600 	//finished with the process handle so close it
       
   601 	clientProcess.Close();
       
   602 
       
   603 	return KErrNone;
       
   604 	}
       
   605 
       
   606 /**
       
   607   Helper function which determines whether the capabilities of the
       
   608   OEM Token are sufficient to permit debug of an application.
       
   609 
       
   610   Normally, we use the AllFiles capability as a proxy which
       
   611   means a Debug Agent can debug non-debuggable executables,
       
   612   provided it has a superset of the capabilities of the executable
       
   613   to be debugged.
       
   614  
       
   615   However, this causes the problem that all OEM Debug Tokens implicitly
       
   616   give the power to debug an AllFiles executable, even if all that
       
   617   is really needed is the power to debug an app with no capabilities,
       
   618   or capabilities other than AllFiles.
       
   619   
       
   620   To address this, we treat the AllFiles capability in a special way.
       
   621   The AllFiles capability in a token is taken to mean that an OEM has
       
   622   signed the token, and hence can debug other executables. But this does
       
   623   not inclue the ability to debug an AllFiles executable. To debug an AllFiles
       
   624   executable, the token must also have TCB.
       
   625 
       
   626   @param aTokenCaps - The PlatSec capabilities of a token
       
   627   @param aTargetCaps - The PlatSec capabilities of a target app to be debugged
       
   628 
       
   629   @return ETrue if authorised for debugging, EFalse otherwise.
       
   630 
       
   631   @leave Any system error code.
       
   632   */
       
   633 TBool CSecuritySvrServer::OEMTokenPermitsDebugL(const TCapabilitySet aTokenCaps, const TCapabilitySet aTargetCaps)
       
   634 	{	
       
   635 	LOG_MSG("CSecuritySvrSession::OEMTokenPermitsDebugL\n");
       
   636 
       
   637 	// Is the token valid - i.e. does it have AllFiles.
       
   638 	if ( !aTokenCaps.HasCapability(ECapabilityAllFiles) )
       
   639 		{
       
   640 		// Token is not valid, as it does not have AllFiles.
       
   641 		LOG_MSG("CSecuritySvrSession::OEMTokenPermitsDebugL - Token does not have AllFiles\n");
       
   642 			
       
   643 		return EFalse;
       
   644 		}
       
   645 
       
   646 	// Token MUST have a strict superset of capabilities
       
   647 	if ( !aTokenCaps.HasCapabilities(aTargetCaps) )
       
   648 		{
       
   649 		// Token does not have at least all the capabilities of the target
       
   650 		LOG_MSG("CSecuritySvrSession::OEMTokenPermitsDebugL - Token does not have superset of target capabilities\n");
       
   651 
       
   652 		return EFalse;
       
   653 		}
       
   654 
       
   655 	// Special case: If the target has AllFiles, the Token must have TCB
       
   656 	if ( aTargetCaps.HasCapability(ECapabilityAllFiles) )
       
   657 		{
       
   658 		// Target has AllFiles, so does the Token have TCB?
       
   659 		if ( !aTokenCaps.HasCapability(ECapabilityTCB) )
       
   660 			{
       
   661 			// Token does not have TCB.
       
   662 			LOG_MSG("CSecuritySvrSession::OEMTokenPermitsDebugL - Token does not have TCB when target has AllFiles\n");
       
   663 	
       
   664 			return EFalse;
       
   665 			}
       
   666 		}
       
   667 
       
   668 	// If we have passed all the above tests, the token permits debug
       
   669 	return ETrue;
       
   670 	}
       
   671 
       
   672 /**
       
   673  * This looks at a debug tokens capability and ensures it is sufficient 
       
   674  * to provide access to the flash partition
       
   675  * @param aTokenCaps Capabilties of the Token
       
   676  * @return TBool Whether or not flash access is permitted
       
   677  */
       
   678 TBool CSecuritySvrServer::OEMTokenPermitsFlashAccessL(const TCapabilitySet aTokenCaps)
       
   679 	{	
       
   680 	//Must have TCB to access flash
       
   681 	return aTokenCaps.HasCapability(ECapabilityTCB);
       
   682 	}
       
   683 
       
   684 //eof
       
   685