os/security/cryptoservices/filebasedcertificateandkeystores/source/generic/server/fsserver.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of the License "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description: 
sl@0
    15
* fstokenserver.cpp
sl@0
    16
*
sl@0
    17
*/
sl@0
    18
sl@0
    19
sl@0
    20
#include "fsserver.h"
sl@0
    21
#include "fstokenutil.h"
sl@0
    22
#include "cfskeystoreserver.h"
sl@0
    23
#include "CKeyStoreSession.h"
sl@0
    24
#include "filecertstore.h"
sl@0
    25
#include "CCertStoreSession.h"
sl@0
    26
#include "CFSCertAppsServer.h"
sl@0
    27
#include "CCertAppsSession.h"
sl@0
    28
#include "FSResources.h"
sl@0
    29
#include "FSDialog.h"
sl@0
    30
#include "tokenserverdebug.h"
sl@0
    31
#include "fstokenservername.h"
sl@0
    32
sl@0
    33
// CTokenServerSession /////////////////////////////////////////////////////////
sl@0
    34
sl@0
    35
CTokenServerSession::CTokenServerSession()
sl@0
    36
	{
sl@0
    37
	}
sl@0
    38
sl@0
    39
inline CTokenServer& CTokenServerSession::Server()
sl@0
    40
	{
sl@0
    41
	return static_cast<CTokenServer&>(const_cast<CServer2&>(*CSession2::Server()));
sl@0
    42
	}
sl@0
    43
sl@0
    44
void CTokenServerSession::CreateL()
sl@0
    45
	{
sl@0
    46
	Server().AddSession();
sl@0
    47
	}
sl@0
    48
sl@0
    49
CTokenServerSession::~CTokenServerSession()
sl@0
    50
	{
sl@0
    51
	Server().DropSession();
sl@0
    52
	}
sl@0
    53
sl@0
    54
/**
sl@0
    55
 * Handle a client request.  Leaving is handled by
sl@0
    56
 * CTokenServerSession::ServiceError() which reports the error code to the
sl@0
    57
 * client.
sl@0
    58
 */
sl@0
    59
void CTokenServerSession::ServiceL(const RMessage2& aMessage)
sl@0
    60
	{
sl@0
    61
#ifdef _DEBUG
sl@0
    62
	// OOM testing
sl@0
    63
	switch (aMessage.Function())
sl@0
    64
		{
sl@0
    65
		case EStartOOMTest:
sl@0
    66
			TokenServerDebug::StartOOMTest();
sl@0
    67
			aMessage.Complete(KErrNone);
sl@0
    68
			return;
sl@0
    69
			
sl@0
    70
		case EIncHeapFailPoint:
sl@0
    71
			TokenServerDebug::IncHeapFailPoint();
sl@0
    72
			aMessage.Complete(KErrNone);
sl@0
    73
			return;
sl@0
    74
			
sl@0
    75
		case EResetHeapFail:
sl@0
    76
			TokenServerDebug::ResetHeapFail();
sl@0
    77
			aMessage.Complete(KErrNone);
sl@0
    78
			return;
sl@0
    79
sl@0
    80
		case EAllocCount:
sl@0
    81
			aMessage.Complete(User::CountAllocCells());
sl@0
    82
			return;
sl@0
    83
		}	
sl@0
    84
#endif
sl@0
    85
	
sl@0
    86
	DoServiceL(aMessage);
sl@0
    87
	}
sl@0
    88
sl@0
    89
/**
sl@0
    90
 * Handle an error from ServiceL() A bad descriptor error implies a badly
sl@0
    91
 * programmed client, so panic it - otherwise report the error to the client.
sl@0
    92
 */
sl@0
    93
void CTokenServerSession::ServiceError(const RMessage2& aMessage, TInt aError)
sl@0
    94
	{
sl@0
    95
	if (aError==KErrBadDescriptor)
sl@0
    96
		{
sl@0
    97
		PanicClient(aMessage, EPanicBadDescriptor);
sl@0
    98
		}
sl@0
    99
	
sl@0
   100
	CSession2::ServiceError(aMessage, aError);
sl@0
   101
	}
sl@0
   102
sl@0
   103
// CTokenServer ////////////////////////////////////////////////////////////////
sl@0
   104
sl@0
   105
inline CTokenServer::CTokenServer() :
sl@0
   106
	CServer2(0, ESharableSessions)
sl@0
   107
	{
sl@0
   108
	}
sl@0
   109
sl@0
   110
CServer2* CTokenServer::NewLC()
sl@0
   111
	{
sl@0
   112
	CTokenServer* self=new(ELeave) CTokenServer;
sl@0
   113
	CleanupStack::PushL(self);
sl@0
   114
	self->ConstructL();
sl@0
   115
	return self;
sl@0
   116
	}
sl@0
   117
sl@0
   118
CTokenServer::~CTokenServer()
sl@0
   119
	{
sl@0
   120
	FSResources::Cleanup();
sl@0
   121
	FSDialog::Cleanup();
sl@0
   122
sl@0
   123
	delete iKeyStoreServer;
sl@0
   124
	delete iCertStoreServer;
sl@0
   125
	delete iCertAppsServer;
sl@0
   126
	}
sl@0
   127
sl@0
   128
/**	2nd phase construction - ensure the timer and server objects are running. */
sl@0
   129
void CTokenServer::ConstructL()
sl@0
   130
	{
sl@0
   131
	FSResources::InitialiseL();
sl@0
   132
	FSDialog::InitialiseL();
sl@0
   133
	
sl@0
   134
	TPtrC serverName(KFSTokenServerName());
sl@0
   135
		// Naming the server thread after the server helps to debug panics
sl@0
   136
#ifdef __WINS__
sl@0
   137
#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   138
	serverName.Set(KFSNewTokenServerName());
sl@0
   139
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   140
#endif // __WINS__
sl@0
   141
		
sl@0
   142
	StartL(serverName);
sl@0
   143
	
sl@0
   144
	// Ensure that the server still exits even if the 1st client fails to connect
sl@0
   145
	iShutdown.ConstructL();
sl@0
   146
	iShutdown.Start();
sl@0
   147
	}
sl@0
   148
sl@0
   149
/** A new session is being created - cancel the shutdown timer if it was running. */
sl@0
   150
void CTokenServer::AddSession()
sl@0
   151
	{
sl@0
   152
	++iSessionCount;
sl@0
   153
	iShutdown.Cancel();
sl@0
   154
	}
sl@0
   155
sl@0
   156
/** A session is being destroyed - start the shutdown timer if it is the last session. */
sl@0
   157
void CTokenServer::DropSession()
sl@0
   158
	{
sl@0
   159
	if (--iSessionCount==0)
sl@0
   160
		{
sl@0
   161
		iShutdown.Start();
sl@0
   162
		}
sl@0
   163
	}
sl@0
   164
sl@0
   165
/** Lazily create key store server object. */
sl@0
   166
CFSKeyStoreServer& CTokenServer::KeyStoreServerL() const
sl@0
   167
	{
sl@0
   168
	if (!iKeyStoreServer)
sl@0
   169
		{
sl@0
   170
		iKeyStoreServer = CFSKeyStoreServer::NewL();
sl@0
   171
		}
sl@0
   172
	
sl@0
   173
	return *iKeyStoreServer;
sl@0
   174
	}
sl@0
   175
sl@0
   176
/** Lazily create cert store server object. */
sl@0
   177
CFSCertStoreServer& CTokenServer::CertStoreServerL() const
sl@0
   178
	{
sl@0
   179
	if (!iCertStoreServer)
sl@0
   180
		{
sl@0
   181
		iCertStoreServer = CFSCertStoreServer::NewL();
sl@0
   182
		}
sl@0
   183
	
sl@0
   184
	return *iCertStoreServer;
sl@0
   185
	}
sl@0
   186
sl@0
   187
/** Lazily create cert apps server object. */
sl@0
   188
CFSCertAppsServer& CTokenServer::CertAppsServerL() const
sl@0
   189
	{
sl@0
   190
	if (!iCertAppsServer)
sl@0
   191
		{
sl@0
   192
		iCertAppsServer = CFSCertAppsServer::NewL();
sl@0
   193
		}
sl@0
   194
	
sl@0
   195
	return *iCertAppsServer;
sl@0
   196
	}
sl@0
   197
sl@0
   198
/** Create a new client session. */
sl@0
   199
CSession2* CTokenServer::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const
sl@0
   200
	{
sl@0
   201
	// The token the client wants to talk to is encoded in the major version number
sl@0
   202
	ETokenEnum token = static_cast<ETokenEnum>(aVersion.iMajor);	
sl@0
   203
sl@0
   204
	// The minor version number represents the version of the protocol
sl@0
   205
	if (aVersion.iMinor != KFSProtolVersion)
sl@0
   206
		{
sl@0
   207
		User::Leave(KErrNotSupported);
sl@0
   208
		}
sl@0
   209
sl@0
   210
	CTokenServerSession* result = NULL;
sl@0
   211
	
sl@0
   212
	switch (token)
sl@0
   213
		{
sl@0
   214
		case EFileKeyStore:
sl@0
   215
			result = KeyStoreServerL().CreateSessionL();
sl@0
   216
			break;
sl@0
   217
sl@0
   218
		case EFileCertStore:
sl@0
   219
			result = CertStoreServerL().CreateSessionL();
sl@0
   220
			break;
sl@0
   221
			
sl@0
   222
		case EFileCertApps:
sl@0
   223
			result = CertAppsServerL().CreateSessionL();
sl@0
   224
			break;
sl@0
   225
			
sl@0
   226
		default:
sl@0
   227
			User::Leave(KErrNotSupported);
sl@0
   228
			break;
sl@0
   229
		}
sl@0
   230
sl@0
   231
	return result;
sl@0
   232
	}
sl@0
   233
sl@0
   234
// CShutdown ///////////////////////////////////////////////////////////////////
sl@0
   235
sl@0
   236
inline CShutdown::CShutdown() :
sl@0
   237
	CTimer(-1)
sl@0
   238
	{
sl@0
   239
	CActiveScheduler::Add(this);
sl@0
   240
	}
sl@0
   241
sl@0
   242
inline void CShutdown::ConstructL()
sl@0
   243
	{
sl@0
   244
	CTimer::ConstructL();
sl@0
   245
	}
sl@0
   246
sl@0
   247
inline void CShutdown::Start()
sl@0
   248
	{
sl@0
   249
	After(KServerShutdownDelay);
sl@0
   250
	}
sl@0
   251
sl@0
   252
/** Initiate server exit when the timer expires. */
sl@0
   253
void CShutdown::RunL()
sl@0
   254
	{
sl@0
   255
	CActiveScheduler::Stop();
sl@0
   256
	}
sl@0
   257
sl@0
   258
// Server startup //////////////////////////////////////////////////////////////
sl@0
   259
sl@0
   260
/**
sl@0
   261
 * Perform all server initialisation, in particular creation of the scheduler
sl@0
   262
 * and server and then run the scheduler.
sl@0
   263
 */
sl@0
   264
static void RunServerL()
sl@0
   265
	{
sl@0
   266
	TPtrC serverName(KFSTokenServerName());
sl@0
   267
	// Naming the server thread after the server helps to debug panics
sl@0
   268
#ifdef __WINS__
sl@0
   269
#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   270
	serverName.Set(KFSNewTokenServerName());
sl@0
   271
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   272
#endif // __WINS__
sl@0
   273
	
sl@0
   274
	User::LeaveIfError(User::RenameThread(serverName));
sl@0
   275
	
sl@0
   276
	// Create and install the active scheduler we need
sl@0
   277
	CActiveScheduler* s=new(ELeave) CActiveScheduler;
sl@0
   278
	CleanupStack::PushL(s);
sl@0
   279
	CActiveScheduler::Install(s);
sl@0
   280
	
sl@0
   281
	// Create the server and leave it on the cleanup stack
sl@0
   282
	CTokenServer::NewLC();
sl@0
   283
	
sl@0
   284
	// Before starting the server, notify client that initialisation is
sl@0
   285
	// complete.
sl@0
   286
	// (note that WINS on EKA1 uses threads since it lacks process emulation)
sl@0
   287
	RProcess::Rendezvous(KErrNone);
sl@0
   288
sl@0
   289
	// Ready to run
sl@0
   290
	CActiveScheduler::Start();
sl@0
   291
	
sl@0
   292
	// Cleanup the server and scheduler
sl@0
   293
	CleanupStack::PopAndDestroy(2);
sl@0
   294
	}
sl@0
   295
sl@0
   296
/** Server process entry point. */
sl@0
   297
TInt E32Main()
sl@0
   298
	{
sl@0
   299
#ifdef _DEBUG
sl@0
   300
	TokenServerDebug::HeapCheckStart();
sl@0
   301
#endif
sl@0
   302
sl@0
   303
	CTrapCleanup* cleanup=CTrapCleanup::New();
sl@0
   304
	TInt r=KErrNoMemory;
sl@0
   305
	if (cleanup)
sl@0
   306
		{
sl@0
   307
		TRAP(r,RunServerL());
sl@0
   308
		delete cleanup;
sl@0
   309
		}
sl@0
   310
sl@0
   311
#ifdef _DEBUG
sl@0
   312
	TokenServerDebug::HeapCheckEnd();
sl@0
   313
#endif
sl@0
   314
	return r;
sl@0
   315
	}
sl@0
   316
sl@0
   317
// Only for wins on EKA1 - WINS loads a DLL and starts a new thread
sl@0
   318
// by calling WinsMain which does the "server" startup