diff -r 000000000000 -r 15bf7259bb7c uiacceltk/hitchcock/TokenServer/SrvSrc/ftokenserver.cpp --- /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 +#include +#include +#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 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 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 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; + } +