kernel/eka/debug/securityServer/src/c_security_svr_server.cpp
changeset 259 57b9594f5772
parent 247 d8d70de2bd36
child 260 a1a318fd91af
child 266 0008ccd16016
equal deleted inserted replaced
247:d8d70de2bd36 259:57b9594f5772
     1 // Copyright (c) 2006-2010 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 	//create session
       
   127 	LOG_MSG("About to call new(ELeave) CSecuritySvrSession()");
       
   128 	CSecuritySvrSession* servSession = new(ELeave) CSecuritySvrSession();
       
   129 
       
   130 	CleanupStack::PushL(servSession);
       
   131 	servSession->ConstructL();
       
   132 	CleanupStack::Pop(servSession);
       
   133 	return servSession;
       
   134 	}
       
   135 
       
   136 /**
       
   137 Manages requests from debug agents to attach to target debug processes
       
   138 
       
   139 Given the debug agent process ID and the target process name:
       
   140 (1) checks whether the pair is already in either of the debug maps, if so
       
   141     then returns KErrAlreadyExists
       
   142 (2) if aPassive == ETrue then just add the pair to the passive map and return
       
   143     whatever the return value of the array write was
       
   144 (3) if aPassive == EFalse then check whether the target debug process is 
       
   145     already reserved by another debug agent. If it is then return KErrInUse,
       
   146     otherwise add the pair to the active debug map and return the status 
       
   147     value of the array write.
       
   148 
       
   149 @param aTargetProcessName original FileName of the process to attach to
       
   150 @param aDebugAgentProcessId process ID of the debug agent
       
   151 @param aPassive ETrue if wish to attach passively, EFalse otherwise
       
   152 
       
   153 @return KErrNone if successfully attached, otherwise another system wide error
       
   154         code as above
       
   155 */
       
   156 TInt CSecuritySvrServer::AttachProcessL(const TDesC& aTargetProcessName, const TProcessId aDebugAgentProcessId, const TBool aPassive)
       
   157 	{
       
   158 	//store the pair of values
       
   159 	LOG_MSG( "CSecuritySvrServer::AttachProcessL()\n" );
       
   160 
       
   161 	CProcessPair *processPair = CProcessPair::NewL(aTargetProcessName, aDebugAgentProcessId);
       
   162 	if(processPair == NULL)
       
   163 		return KErrNoMemory;
       
   164 
       
   165 	//check whether the pair already exists in the active debug map
       
   166 	for(TInt i=0; i<iActiveDebugMap.Count(); i++)
       
   167 		{
       
   168 		if(*processPair == *(iActiveDebugMap[i]))
       
   169 			{
       
   170 			//process already exists
       
   171 			LOG_MSG( "  AttachProcessL() error : KErrAlreadyExists in active map\n" );
       
   172 			delete processPair;
       
   173 			return KErrAlreadyExists;
       
   174 			}
       
   175 		}
       
   176 
       
   177 	//check whether the pair already exists in the passive map
       
   178 	for(TInt i=0; i<iPassiveDebugMap.Count(); i++)
       
   179 		{
       
   180 		if(*processPair == *(iPassiveDebugMap[i]))
       
   181 			{
       
   182 			//process already exists
       
   183 			LOG_MSG( "  AttachProcessL() error : KErrAlreadyExists in passive map\n" );
       
   184 			delete processPair;
       
   185 			return KErrAlreadyExists;
       
   186 			}
       
   187 		}
       
   188 
       
   189 	if(aPassive)
       
   190 		{
       
   191 		//just add the pair and return
       
   192 		TInt err = iPassiveDebugMap.Append(processPair);
       
   193 		if(err != KErrNone)
       
   194 			{
       
   195 			// couldn't add pair for some unknown reason, so delete the pair
       
   196 			LOG_MSG2( "  AttachProcessL() error %d appending passive process pair \n", err );
       
   197 			delete processPair;
       
   198 			}
       
   199 		return err;
       
   200 		}
       
   201 	else
       
   202 		{
       
   203 		//check whether the process Id has already been reserved
       
   204 		for(TInt i=0; i<iActiveDebugMap.Count(); i++)
       
   205 			{
       
   206 			if(processPair->ProcessNameMatches(*(iActiveDebugMap[i])))
       
   207 				{
       
   208 				//process already being debugged
       
   209 				LOG_MSG( "  AttachProcessL() error : process already being debugged\n" );
       
   210 				delete processPair;
       
   211 				return KErrInUse;
       
   212 				}
       
   213 			}
       
   214 		//try to add the pair	
       
   215 		TInt err = iActiveDebugMap.Append(processPair);
       
   216 		if(err != KErrNone)
       
   217 			{
       
   218 			// couldn't add pair for some unknown reason, so delete the pair
       
   219 			LOG_MSG2( "  AttachProcessL() error %d appending active process pair \n", err );
       
   220 			delete processPair;
       
   221 			}
       
   222 		return err;
       
   223 		}
       
   224 	}
       
   225 
       
   226 /*
       
   227 Detach from debugging the specified process
       
   228 
       
   229 @param aTargetProcessName name of the process to detach from
       
   230 @param aDebugAgentProcessId process ID of the debug agent
       
   231 
       
   232 @return KErrNone if successfully detached, KErrNotFound if an attempt is made
       
   233         to detach from a process which the debug agent hasn't previously attached to
       
   234 */
       
   235 TInt CSecuritySvrServer::DetachProcess(const TDesC& aTargetProcessName, const TProcessId aDebugAgentProcessId)
       
   236 	{
       
   237 	//check whether the pair is in the active debug map
       
   238 	for(TInt i=0; i<iActiveDebugMap.Count(); i++)
       
   239 		{
       
   240 		if(iActiveDebugMap[i]->Equals(aTargetProcessName, aDebugAgentProcessId))
       
   241 			{
       
   242 			//remove the process pair from the active debug map
       
   243 			delete iActiveDebugMap[i];
       
   244 			iActiveDebugMap.Remove(i);
       
   245 			return KErrNone;
       
   246 			}
       
   247 		}
       
   248 
       
   249 	//check whether the pair is in the passive debug map
       
   250 	for(TInt i=0; i<iPassiveDebugMap.Count(); i++)
       
   251 		{
       
   252 		if(iPassiveDebugMap[i]->Equals(aTargetProcessName, aDebugAgentProcessId))
       
   253 			{
       
   254 			//remove the process pair from the active debug map
       
   255 			delete iPassiveDebugMap[i];
       
   256 			iPassiveDebugMap.Remove(i);
       
   257 			return KErrNone;
       
   258 			}
       
   259 		}
       
   260 
       
   261 	//process pair wasn't in either map
       
   262 	return KErrNotFound;
       
   263 	}
       
   264 
       
   265 /**
       
   266 Given a debug agent process ID, removes all references to that debug agent
       
   267 from the debug maps
       
   268 
       
   269 @param aMessage message from the debug agent
       
   270 
       
   271 @return returns KErrNone if successful, another system wide error code otherwise
       
   272 */
       
   273 void CSecuritySvrServer::DetachAllProcesses(const TProcessId aDebugAgentProcessId)
       
   274 	{
       
   275 	//check whether the debug agent process ID is in the active debug map
       
   276 	for(TInt i=iActiveDebugMap.Count()-1; i>=0; i--)
       
   277 		{
       
   278 		if(iActiveDebugMap[i]->ProcessIdMatches(aDebugAgentProcessId))
       
   279 			{
       
   280 			//remove the process pair from the active debug map
       
   281 			delete iActiveDebugMap[i];
       
   282 			iActiveDebugMap.Remove(i);
       
   283 			}
       
   284 		}
       
   285 
       
   286 	//check whether the debug agent process ID is in the passive debug map
       
   287 	for(TInt i=iPassiveDebugMap.Count()-1; i>=0; i--)
       
   288 		{
       
   289 		if(iPassiveDebugMap[i]->ProcessIdMatches(aDebugAgentProcessId))
       
   290 			{
       
   291 			//remove the process pair from the passive debug map
       
   292 			delete iPassiveDebugMap[i];
       
   293 			iPassiveDebugMap.Remove(i);
       
   294 			}
       
   295 		}
       
   296 	}
       
   297 
       
   298 /*
       
   299 Check whether the specified debug agent is attaced to the specfied target
       
   300 process.
       
   301 
       
   302 @param aTargetThreadId thread ID of a thread in the target process
       
   303 @param aMessage a message which originates with the debug agent
       
   304 @param aPassive if EFalse then checks whether the debug agent is the active
       
   305        debugger of the target process. If ETrue then checks whether the debug
       
   306        agent is attached to the target process, irrespective of whether it is
       
   307        attached passively or actively
       
   308 
       
   309 @return ETrue if attached, EFalse otherwise
       
   310 */
       
   311 TBool CSecuritySvrServer::CheckAttached(const TThreadId aTargetThreadId, const RMessage2& aMessage, const TBool aPassive)
       
   312 	{
       
   313 	
       
   314 	//get a handle to the target thread
       
   315 	RThread targetThread;
       
   316 	TInt err = targetThread.Open(aTargetThreadId);
       
   317 	if(err != KErrNone)
       
   318 		{
       
   319 		return EFalse;
       
   320 		}
       
   321 
       
   322 	//get a handle to the target process
       
   323 	RProcess targetProcess;
       
   324 	err = targetThread.Process(targetProcess);
       
   325 	//finshed with the thread handle so close it
       
   326 	targetThread.Close();
       
   327 	if(err != KErrNone)
       
   328 		return EFalse;
       
   329 
       
   330 	//get the target process' file name
       
   331 	TFileName targetFileName = targetProcess.FileName();
       
   332 
       
   333 	// Tamperproofing. Ensure that the debug agent really has a superset
       
   334 	// of the target process PlatSec capabilities, as authorised
       
   335 	// by an OEM Debug Token (if any)
       
   336 
       
   337 	TSecurityInfo targetSecInfo(targetProcess);
       
   338 
       
   339 	// Now compare the capabilities, to ensure the DebugAgent has been authorised with
       
   340 	// sufficient capabilities from its OEM Debug token
       
   341 	CSecuritySvrSession* session = (CSecuritySvrSession*)aMessage.Session();
       
   342 
       
   343 	// Presume we need to check the target process is debuggable unless a valid OEM Debug token in effect?
       
   344 	if (!OEMTokenPermitsDebugL(session->GetOEMDebugCapabilities(), targetSecInfo.iCaps) )
       
   345 		{
       
   346 		// No debug token therefore check if the process is debuggable
       
   347 		err = iKernelDriver.IsDebuggable(targetProcess.Id());
       
   348 		}
       
   349 
       
   350 	//finished with the process handle so close it
       
   351 	targetProcess.Close();
       
   352 
       
   353 	if (err != KErrNone)
       
   354 	{
       
   355 		// The process was not marked as debuggable by the loader, and the OEM
       
   356 		// debug token did not override the lack of a debuggable bit.
       
   357 		// The process was not marked as debuggable by the loader
       
   358 		return EFalse;
       
   359 	}
       
   360 
       
   361 	return CheckAttachedProcess(targetFileName, aMessage, aPassive);
       
   362 	}
       
   363 
       
   364 /*
       
   365 Check whether the specified debug agent is attaced to the specfied target
       
   366 process.
       
   367 
       
   368 @param aTargetProcessId process ID of the target process
       
   369 @param aMessage a message which originates with the debug agent
       
   370 @param aPassive if EFalse then checks whether the debug agent is the active
       
   371        debugger of the target process. If ETrue then checks whether the debug
       
   372        agent is attached to the target process, irrespective of whether it is
       
   373        attached passively or actively
       
   374 
       
   375 @return ETrue if attached, EFalse otherwise
       
   376 */
       
   377 TBool CSecuritySvrServer::CheckAttached(const TProcessId aTargetProcessId, const RMessage2& aMessage, const TBool aPassive)
       
   378 	{
       
   379 	//get a handle to the target process
       
   380 	RProcess targetProcess;
       
   381 	TInt err =targetProcess.Open(aTargetProcessId);
       
   382 	if(err != KErrNone)
       
   383 		{
       
   384 		return EFalse;
       
   385 		}
       
   386 
       
   387 	//get the target process' file name
       
   388 	TFileName targetFileName = targetProcess.FileName();
       
   389 
       
   390 	// Tamperproofing. Ensure that the debug agent really has a superset
       
   391 	// of the target process PlatSec capabilities, as authorised
       
   392 	// by an OEM Debug Token (if any)
       
   393 
       
   394 	TSecurityInfo targetSecInfo(targetProcess);
       
   395 
       
   396 	// Now compare the capabilities, to ensure the DebugAgent has been authorised with
       
   397 	// sufficient capabilities from its OEM Debug token
       
   398 	CSecuritySvrSession* session = (CSecuritySvrSession*)aMessage.Session();
       
   399 
       
   400 	// Presume we need to check the target process is debuggable unless a valid OEM Debug token in effect?
       
   401 	if ( !OEMTokenPermitsDebugL(session->GetOEMDebugCapabilities(), targetSecInfo.iCaps) )
       
   402 		{
       
   403 		// No debug token therefore check if the process is debuggable
       
   404 		err = iKernelDriver.IsDebuggable(targetProcess.Id());
       
   405 		}
       
   406 
       
   407 	//finished with the process handle so close it
       
   408 	targetProcess.Close();
       
   409 
       
   410 	if (err != KErrNone)
       
   411 	{
       
   412 		return EFalse;
       
   413 	}
       
   414 
       
   415 	return CheckAttachedProcess(targetFileName, aMessage, aPassive);
       
   416 	}
       
   417 
       
   418 /*
       
   419 Check whether the specified debug agent is attaced to the specfied target
       
   420 process.
       
   421 
       
   422 @param aTargetProcessName 
       
   423 @param aMessage a message which originates with the debug agent
       
   424 
       
   425 @return ETrue if attached, EFalse otherwise
       
   426 */
       
   427 TBool CSecuritySvrServer::CheckAttachedProcess(const TDesC& aTargetProcessName, const RMessage2& aMessage, const TBool aPassive) const
       
   428 	{
       
   429 	//get the debug agent's process id
       
   430 	TProcessId clientProcessId = 0;
       
   431 	TInt err = GetProcessIdFromMessage(clientProcessId, aMessage);
       
   432 	if(err != KErrNone)
       
   433 		return EFalse;
       
   434 
       
   435 	//check permissions
       
   436 	if(aPassive)
       
   437 		return IsDebugger(aTargetProcessName, clientProcessId);
       
   438 	else
       
   439 		return IsActiveDebugger(aTargetProcessName, clientProcessId);
       
   440 	}
       
   441 
       
   442 /**
       
   443 Tests whether the debug agent is attached actively to the target debug process
       
   444 
       
   445 @param aTargetProcessName target debug process' FileName
       
   446 @param aDebugAgentProcessId process ID of a debug agent
       
   447 
       
   448 @return ETrue if the specified debug agent is actively attached to the 
       
   449         specified target debug process, EFalse otherwise
       
   450 */
       
   451 TBool CSecuritySvrServer::IsActiveDebugger(const TDesC& aTargetProcessName, const TProcessId aDebugAgentProcessId) const
       
   452 	{
       
   453 	//check whether the pair is in the active debug map
       
   454 	for(TInt i=0; i<iActiveDebugMap.Count(); i++)
       
   455 		{
       
   456 		if(iActiveDebugMap[i]->Equals(aTargetProcessName, aDebugAgentProcessId))
       
   457 			return ETrue;
       
   458 		}
       
   459 	//not found so return false
       
   460 	return EFalse;
       
   461 	}
       
   462 
       
   463 /**
       
   464 Tests whether the target process is being debugged
       
   465 
       
   466 @param aTargetProcessName target process' FileName
       
   467 @param aPassive indicates whether to check for the process being actively debugged,
       
   468 or passively debugged
       
   469 
       
   470 @return ETrue if the specified target process is being debugged,
       
   471         EFalse otherwise
       
   472 */
       
   473 TBool CSecuritySvrServer::IsDebugged(const TDesC& aTargetProcessName, const TBool aPassive) const
       
   474 	{
       
   475 	//get a reference to the appropriate list
       
   476 	const RPointerArray<CProcessPair>& map = (aPassive) ? iPassiveDebugMap : iActiveDebugMap;
       
   477 
       
   478 	//iterate through the map trying to match the aTargetProcessName
       
   479 	for(TInt i=0; i<map.Count(); i++)
       
   480 		{
       
   481 		if(map[i]->ProcessNameMatches(aTargetProcessName))
       
   482 			{
       
   483 			return ETrue;
       
   484 			}
       
   485 		}
       
   486 	return EFalse;
       
   487 	}
       
   488 
       
   489 /**
       
   490 Tests whether the debug agent is attached to the target debug process
       
   491 
       
   492 @param aTargetProcessName target debug process' FileName
       
   493 @param aDebugAgentProcessId process ID of a debug agent
       
   494 
       
   495 @return ETrue if the specified debug agent is attached to the 
       
   496         specified target debug process (regardless of whether it is attached
       
   497 	passively or actively), EFalse otherwise
       
   498 */
       
   499 TBool CSecuritySvrServer::IsDebugger(const TDesC& aTargetProcessName, const TProcessId aDebugAgentProcessId) const
       
   500 	{
       
   501 	//check whether the pair is in the active debug map
       
   502 	if(IsActiveDebugger(aTargetProcessName, aDebugAgentProcessId))
       
   503 		return ETrue; 
       
   504 
       
   505 	//check whether the pair is in the passive debug map
       
   506 	for(TInt i=0; i<iPassiveDebugMap.Count(); i++)
       
   507 		{
       
   508 		if(iPassiveDebugMap[i]->Equals(aTargetProcessName, aDebugAgentProcessId))
       
   509 			return ETrue;
       
   510 		}
       
   511 	//not found so return false
       
   512 	return EFalse;
       
   513 	}
       
   514 
       
   515 /**
       
   516 Decrements the server's count of how many sessions are connected to it and
       
   517 starts the shutdown timer if there are no sessions connected
       
   518 */
       
   519 void CSecuritySvrServer::SessionClosed()
       
   520 	{
       
   521 	if(--iSessionCount < 1)
       
   522 		{
       
   523 		iShutdown.Start();
       
   524 		}
       
   525 	}
       
   526 
       
   527 /**
       
   528 Increments the servers count of how many sessions are connected to it and
       
   529 cancels the shutdown timer if it is running
       
   530 */
       
   531 void CSecuritySvrServer::SessionOpened()
       
   532 	{
       
   533 	iSessionCount++;
       
   534 	iShutdown.Cancel();
       
   535 	}
       
   536 
       
   537 /** 
       
   538   Get the process id of the thread which sent aMessage
       
   539   @param aProcessId process id of the thread which sent aMessage
       
   540   @param aMessage message object sent by thread 
       
   541 
       
   542   @return KErrNone if aProcessId could be set, or one of the system wide error codes if not
       
   543   */
       
   544 TInt CSecuritySvrServer::GetProcessIdFromMessage(TProcessId& aProcessId, const RMessage2& aMessage) const
       
   545 	{
       
   546 	//get the debug agent's thread
       
   547 	RThread clientThread;
       
   548 	TInt err = aMessage.Client(clientThread);
       
   549 	if(err != KErrNone)
       
   550 		{
       
   551 		return err;
       
   552 		}
       
   553 
       
   554 	//get the debug agent's process
       
   555 	RProcess clientProcess;
       
   556 	err = clientThread.Process(clientProcess);
       
   557 
       
   558 	//finished with the thread handle so close it
       
   559 	clientThread.Close();
       
   560 
       
   561 	//check if there was an error from getting the process
       
   562 	if(err != KErrNone)
       
   563 		{
       
   564 		return err;
       
   565 		}
       
   566 
       
   567 	//get the debug agent's process id
       
   568 	aProcessId = clientProcess.Id();
       
   569 
       
   570 	//finished with the process handle so close it
       
   571 	clientProcess.Close();
       
   572 
       
   573 	return KErrNone;
       
   574 	}
       
   575 
       
   576 /**
       
   577   Helper function which determines whether the capabilities of the
       
   578   OEM Token are sufficient to permit debug of an application.
       
   579 
       
   580   Normally, we use the AllFiles capability as a proxy which
       
   581   means a Debug Agent can debug non-debuggable executables,
       
   582   provided it has a superset of the capabilities of the executable
       
   583   to be debugged.
       
   584  
       
   585   However, this causes the problem that all OEM Debug Tokens implicitly
       
   586   give the power to debug an AllFiles executable, even if all that
       
   587   is really needed is the power to debug an app with no capabilities,
       
   588   or capabilities other than AllFiles.
       
   589   
       
   590   To address this, we treat the AllFiles capability in a special way.
       
   591   The AllFiles capability in a token is taken to mean that an OEM has
       
   592   signed the token, and hence can debug other executables. But this does
       
   593   not inclue the ability to debug an AllFiles executable. To debug an AllFiles
       
   594   executable, the token must also have TCB.
       
   595 
       
   596   @param aTokenCaps - The PlatSec capabilities of a token
       
   597   @param aTargetCaps - The PlatSec capabilities of a target app to be debugged
       
   598 
       
   599   @return ETrue if authorised for debugging, EFalse otherwise.
       
   600 
       
   601   @leave Any system error code.
       
   602   */
       
   603 TBool CSecuritySvrServer::OEMTokenPermitsDebugL(const TCapabilitySet aTokenCaps, const TCapabilitySet aTargetCaps)
       
   604 	{	
       
   605 	LOG_MSG("CSecuritySvrSession::OEMTokenPermitsDebugL\n");
       
   606 
       
   607 	// Is the token valid - i.e. does it have AllFiles.
       
   608 	if ( !aTokenCaps.HasCapability(ECapabilityAllFiles) )
       
   609 		{
       
   610 		// Token is not valid, as it does not have AllFiles.
       
   611 		LOG_MSG("CSecuritySvrSession::OEMTokenPermitsDebugL - Token does not have AllFiles\n");
       
   612 			
       
   613 		return EFalse;
       
   614 		}
       
   615 
       
   616 	// Token MUST have a strict superset of capabilities
       
   617 	if ( !aTokenCaps.HasCapabilities(aTargetCaps) )
       
   618 		{
       
   619 		// Token does not have at least all the capabilities of the target
       
   620 		LOG_MSG("CSecuritySvrSession::OEMTokenPermitsDebugL - Token does not have superset of target capabilities\n");
       
   621 
       
   622 		return EFalse;
       
   623 		}
       
   624 
       
   625 	// Special case: If the target has AllFiles, the Token must have TCB
       
   626 	if ( aTargetCaps.HasCapability(ECapabilityAllFiles) )
       
   627 		{
       
   628 		// Target has AllFiles, so does the Token have TCB?
       
   629 		if ( !aTokenCaps.HasCapability(ECapabilityTCB) )
       
   630 			{
       
   631 			// Token does not have TCB.
       
   632 			LOG_MSG("CSecuritySvrSession::OEMTokenPermitsDebugL - Token does not have TCB when target has AllFiles\n");
       
   633 	
       
   634 			return EFalse;
       
   635 			}
       
   636 		}
       
   637 
       
   638 	// If we have passed all the above tests, the token permits debug
       
   639 	return ETrue;
       
   640 	}
       
   641 
       
   642 /**
       
   643  * This looks at a debug tokens capability and ensures it is sufficient 
       
   644  * to provide access to the flash partition
       
   645  * @param aTokenCaps Capabilties of the Token
       
   646  * @return TBool Whether or not flash access is permitted
       
   647  */
       
   648 TBool CSecuritySvrServer::OEMTokenPermitsFlashAccessL(const TCapabilitySet aTokenCaps)
       
   649 	{	
       
   650 	//Must have TCB to access flash
       
   651 	return aTokenCaps.HasCapability(ECapabilityTCB);
       
   652 	}
       
   653 
       
   654 //eof
       
   655