--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/TokenServer/SrvSrc/ftokenserver.cpp Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,288 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Server implementation fo share files in application private gage
+* with controlled way
+*
+*/
+
+
+
+#include <e32std.h>
+#include <f32file.h>
+#include <e32math.h>
+#include "ftokenserver.h"
+#include "ftokenconsts.h"
+
+void CFsTokenServer::NewLC()
+ {
+ CFsTokenServer* pS = new (ELeave) CFsTokenServer;
+ CleanupStack::PushL(pS);
+ pS->ConstructL();
+ }
+
+void CFsTokenServer::ConstructL()
+ {
+ User::LeaveIfError( iFs.Connect() );
+ User::LeaveIfError( iFs.ShareProtected() );
+ StartL(FTOKEN_SERVER_NAME);
+ }
+
+CSession2* CFsTokenServer::NewSessionL(const TVersion& /*aVersion*/,const RMessage2& /*aMessage*/) const
+ {
+ return new(ELeave) CFsTokenServerSession();
+ }
+
+void CFsTokenServer::HandleClientExit(const CSession2* aClient)
+ { // Todo: We could invent somekind notify here to notify
+ // possible user of a file to release its handle as well..
+ for(TInt index = iTokens.Find(*aClient, TToken::CompareOwner);
+ index != KErrNotFound;
+ index = iTokens.Find(*aClient, TToken::CompareOwner) )
+ {
+ if (iTokens[index].iHasSubToken == 0)
+ {
+ delete iTokens[index].iFileName;
+ }
+ iTokens.Remove(index);
+ }
+ }
+
+CFsTokenServer::~CFsTokenServer()
+ {
+ for(TInt count = iTokens.Count(); count > 0; count-- )
+ {
+ if (iTokens[0].iHasSubToken == 0)
+ {
+ delete iTokens[0].iFileName;
+ }
+ iTokens.Remove(0);
+ }
+
+ iFs.Close();
+ iTokens.Close();
+ }
+
+void CFsTokenServer::AddTokenL(const RMessage2& aMessage)
+ {
+ HBufC* fileName = 0;
+ TKeyArrayFix tokenKey(_FOFF(TToken, iToken), ECmpTInt64);
+
+ TInt function = aMessage.Function();
+ switch(aMessage.Function())
+ {
+ case EGenerateTokenBasedOnName:
+ //==================================================
+ // 1) filename
+ //===================================================
+ {
+ User::Leave(KErrNotSupported);
+/* TInt msgLenght = aMessage.GetDesLength(1);
+ if (length > 0)
+ {
+ fileName = HBufC::NewLC(length);
+ TPtr ptr = fileName->Des();
+ aMessage.Read(1,ptr);
+ if (iFs.IsValidName(ptr))
+ {
+
+ }
+ else
+ {
+ User::Leave(KErrArgument);
+ }
+ }
+ else
+ {
+ User::Leave(KErrArgument);
+ }
+*/
+ break;
+ }
+ case EGenerateTokenBasedOnOpenHandle:
+ //===================================================
+ // 2) handle
+ //===================================================
+ {
+ // 2.1) check that we are able to open the file
+ RFile file;
+ User::LeaveIfError(file.AdoptFromClient(aMessage,2,3));
+ // 2.2) resolve full filename
+ TFileName fn;
+ file.FullName(fn);
+ file.Close();
+
+ fileName = fn.AllocLC();
+ break;
+ }
+ case EGenerateTokenBasedOnAnotherToken:
+ // ==================================================
+ // 3) token
+ //===================================================
+ {
+ TInt64 token = 0;
+ TPckg<TInt64> buf(token);
+
+ // 3.1) just check that client uid and token match
+ aMessage.ReadL(1,buf);
+ TInt index = iTokens.Find(token, TToken::CompareToken);
+ User::LeaveIfError( index );
+
+ if (iTokens[index].iPolicy.CheckPolicy(aMessage))
+ {
+ // set a pointer to existing buffer, when deleting
+ // this must be handled slightly different way
+ // but theres no need to spend lots of mem
+ // for duplicate filenames
+ fileName = iTokens[index].iFileName;
+
+ // there shouldn't be more than one subtoken per token ever
+ ASSERT(iTokens[index].iHasSubToken==EFalse);
+ iTokens[index].iHasSubToken = ETrue;
+ }
+ else
+ {
+ User::Leave(KErrPermissionDenied);
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+ // add token to array
+ TInt64 newToken = User::NTickCount();
+
+ for(newToken = Math::FRand(newToken);
+ iTokens.Find(newToken, TToken::CompareToken) != KErrNotFound;
+ newToken = User::NTickCount())
+ {
+ newToken = Math::FRand(newToken);
+ }
+
+ TToken entry;
+ entry.iToken = newToken;
+ entry.iFileName = fileName;
+ entry.iOwner = aMessage.Session();
+
+ TPckg<TSecurityPolicy> policyBuf(entry.iPolicy);
+ aMessage.ReadL(0, policyBuf);
+
+ User::LeaveIfError(iTokens.Append(entry));
+ if (function == EGenerateTokenBasedOnOpenHandle)
+ {
+ CleanupStack::Pop(); // filename
+ }
+ }
+
+void CFsTokenServer::OpenFileL(const RMessage2& aMessage)
+ {
+ // find token based on client uid and given token
+ TInt64 token = 0;
+ TPckg<TInt64> buf(token);
+ aMessage.ReadL(1,buf);
+
+ TInt index = iTokens.Find(token, TToken::CompareToken);
+ User::LeaveIfError(index);
+
+ if (iTokens[index].iPolicy.CheckPolicy(aMessage))
+ { // authorized client requests file
+ RFile file;
+ // Todo: what should the mode be ??
+ User::LeaveIfError(file.Open(iFs, *(iTokens[index].iFileName), EFileShareReadersOnly));
+ CleanupClosePushL(file);
+ User::LeaveIfError(file.TransferToClient(aMessage, 0));
+ CleanupStack::PopAndDestroy(); //file
+ }
+ else
+ {
+ User::Leave(KErrPermissionDenied);
+ }
+ }
+
+
+CFsTokenServerSession::CFsTokenServerSession()
+ {
+ }
+
+CFsTokenServerSession::~CFsTokenServerSession()
+ {
+ ((CFsTokenServer*)(Server()))->HandleClientExit(this);
+ }
+
+void CFsTokenServerSession::ServiceL(const RMessage2& aMessage)
+ {
+ CFsTokenServer* server = (CFsTokenServer*)( Server() );
+ switch(aMessage.Function())
+ {
+ case EGenerateTokenBasedOnName:
+ case EGenerateTokenBasedOnOpenHandle:
+ case EGenerateTokenBasedOnAnotherToken:
+ {
+ server->AddTokenL(aMessage);
+ break;
+ }
+ case EOpenHandleForToken:
+ {
+ server->OpenFileL(aMessage);
+ // Todo: We could set somekind penalty to client that continuously
+ // passes wrong tokens (i.e. seems to be guessing), e.g. panic it...
+ break;
+ }
+
+ default:
+ aMessage.Complete(KErrNotSupported);
+ break;
+ }
+ if (!aMessage.IsNull())
+ {
+ aMessage.Complete(KErrNone);
+ }
+ }
+
+static void RunServerL()
+ {
+ // Create Scheduler, obsolete nowdays ?
+ CActiveScheduler* s=new(ELeave) CActiveScheduler;
+ CleanupStack::PushL(s);
+ CActiveScheduler::Install(s);
+
+ CFsTokenServer::NewLC();
+
+ RProcess::Rendezvous(KErrNone);
+
+ CActiveScheduler::Start();
+
+ CleanupStack::PopAndDestroy(2);
+ }
+
+
+TInt E32Main()
+ {
+ TInt err = User::RenameThread(FTOKEN_SERVER_NAME);
+ if ( err != KErrNone )
+ {
+ return err;
+ }
+
+ // create CCleanup
+ CTrapCleanup * cleanup = CTrapCleanup::New();
+ if (cleanup)
+ {
+ TRAP(err, RunServerL());
+ delete cleanup;
+ }
+
+ return err;
+ }
+